1+ import axios from "axios" ;
12import bcrypt from "bcrypt" ;
23import { FastifyInstance , FastifyReply , FastifyRequest } from "fastify" ;
34import jwt from "jsonwebtoken" ;
5+ import { track } from "../lib/hog" ;
46import { checkToken } from "../lib/jwt" ;
7+ import { forgotPassword } from "../lib/nodemailer/auth/forgot-password" ;
58import { prisma } from "../prisma" ;
69
710export function authRoutes ( fastify : FastifyInstance ) {
@@ -42,7 +45,7 @@ export function authRoutes(fastify: FastifyInstance) {
4245 } ) ;
4346 }
4447
45- await prisma . user . create ( {
48+ const user = await prisma . user . create ( {
4649 data : {
4750 email,
4851 password : await bcrypt . hash ( password , 10 ) ,
@@ -51,13 +54,116 @@ export function authRoutes(fastify: FastifyInstance) {
5154 } ,
5255 } ) ;
5356
57+ const hog = track ( ) ;
58+
59+ hog . capture ( {
60+ event : "user_registered" ,
61+ distinctId : user . id ,
62+ } ) ;
63+
5464 reply . send ( {
5565 success : true ,
5666 } ) ;
5767 }
5868 ) ;
5969
60- // User login route
70+ // Forgot password & generate code
71+ fastify . post (
72+ "/api/v1/auth/password-reset" ,
73+ async ( request : FastifyRequest , reply : FastifyReply ) => {
74+ const { email, link } = request . body as { email : string ; link : string } ;
75+
76+ let user = await prisma . user . findUnique ( {
77+ where : { email } ,
78+ } ) ;
79+
80+ if ( ! user ) {
81+ reply . code ( 401 ) . send ( {
82+ message : "Invalid email" ,
83+ success : false ,
84+ } ) ;
85+ }
86+
87+ function generateRandomCode ( ) {
88+ const min = 100000 ; // Minimum 6-digit number
89+ const max = 999999 ; // Maximum 6-digit number
90+ return Math . floor ( Math . random ( ) * ( max - min + 1 ) ) + min ;
91+ }
92+
93+ const code = generateRandomCode ( ) ;
94+
95+ const uuid = await prisma . passwordResetToken . create ( {
96+ data : {
97+ userId : user ! . id ,
98+ code : String ( code ) ,
99+ } ,
100+ } ) ;
101+
102+ forgotPassword ( email , String ( code ) , link , uuid . id ) ;
103+
104+ reply . send ( {
105+ success : true ,
106+ } ) ;
107+ }
108+ ) ;
109+
110+ // Check code & uuid us valid
111+ fastify . post (
112+ "/api/v1/auth/password-reset/code" ,
113+ async ( request : FastifyRequest , reply : FastifyReply ) => {
114+ const { code, uuid } = request . body as { code : string ; uuid : string } ;
115+
116+ const reset = await prisma . passwordResetToken . findUnique ( {
117+ where : { code : code , id : uuid } ,
118+ } ) ;
119+
120+ if ( ! reset ) {
121+ reply . code ( 401 ) . send ( {
122+ message : "Invalid Code" ,
123+ success : false ,
124+ } ) ;
125+ } else {
126+ reply . send ( {
127+ success : true ,
128+ } ) ;
129+ }
130+ }
131+ ) ;
132+
133+ // Reset users password via code
134+ fastify . post (
135+ "/api/v1/auth/password-reset/password" ,
136+ async ( request : FastifyRequest , reply : FastifyReply ) => {
137+ const { password, code } = request . body as {
138+ password : string ;
139+ code : string ;
140+ } ;
141+
142+ const user = await prisma . passwordResetToken . findUnique ( {
143+ where : { code : code } ,
144+ } ) ;
145+
146+ if ( ! user ) {
147+ reply . code ( 401 ) . send ( {
148+ message : "Invalid Code" ,
149+ success : false ,
150+ } ) ;
151+ }
152+
153+ await prisma . user . update ( {
154+ where : { id : user ! . userId } ,
155+ data : {
156+ password : await bcrypt . hash ( password , 10 ) ,
157+ } ,
158+ } ) ;
159+
160+ reply . send ( {
161+ success : true ,
162+ } ) ;
163+ }
164+ ) ;
165+
166+ // User password login route
61167 fastify . post (
62168 "/api/v1/auth/login" ,
63169 {
@@ -137,6 +243,133 @@ export function authRoutes(fastify: FastifyInstance) {
137243 }
138244 ) ;
139245
246+ // Checks if a user is SSO or password
247+ fastify . post (
248+ "/api/v1/auth/sso/check" ,
249+ async ( request : FastifyRequest , reply : FastifyReply ) => {
250+ let { email } = request . body as {
251+ email : string ;
252+ } ;
253+
254+ let user = await prisma . user . findUnique ( {
255+ where : { email } ,
256+ } ) ;
257+
258+ if ( ! user ) {
259+ reply . code ( 401 ) . send ( {
260+ message : "Invalid email" ,
261+ success : false ,
262+ } ) ;
263+ }
264+
265+ const authtype = await prisma . config . findMany ( {
266+ where : {
267+ sso_active : true ,
268+ } ,
269+ } ) ;
270+
271+ const provider = await prisma . provider . findMany ( ) ;
272+ const oauth = provider [ 0 ] ;
273+
274+ console . log ( authtype ) ;
275+
276+ if ( authtype . length === 0 ) {
277+ reply . code ( 200 ) . send ( {
278+ success : true ,
279+ message : "SSO not enabled" ,
280+ oauth : false ,
281+ } ) ;
282+ }
283+
284+ const url = "https://github.com/login/oauth/authorize" ;
285+
286+ reply . send ( {
287+ oauth : true ,
288+ success : true ,
289+ ouath_url : `${ url } ?client_id=${ oauth . clientId } &redirect_uri=${ oauth . redirectUri } &state=${ email } &login=${ email } &scope=user` ,
290+ } ) ;
291+ }
292+ ) ;
293+
294+ // SSO api callback route
295+ fastify . get (
296+ "/api/v1/auth/sso/login/callback" ,
297+ async ( request : FastifyRequest , reply : FastifyReply ) => {
298+ const { code, state } = request . query as { code : string ; state : string } ;
299+
300+ const provider = await prisma . provider . findFirst ( { } ) ;
301+
302+ const data = await axios . post (
303+ `https://github.com/login/oauth/access_token` ,
304+ {
305+ client_id : provider ?. clientId ,
306+ client_secret : provider ?. clientSecret ,
307+ code : code ,
308+ redirect_uri : provider ?. redirectUri ,
309+ } ,
310+ {
311+ headers : {
312+ Accept : "application/json" ,
313+ } ,
314+ }
315+ ) ;
316+
317+ const access_token = data . data ;
318+
319+ if ( access_token ) {
320+ const gh = await axios . get ( `https://api.github.com/user/emails` , {
321+ headers : {
322+ Accept : "application/vnd.github+json" ,
323+ Authorization : `token ${ access_token . access_token } ` ,
324+ } ,
325+ } ) ;
326+
327+ const emails = gh . data ;
328+
329+ const filter = emails . filter ( ( e : any ) => e . primary === true ) ;
330+
331+ let user = await prisma . user . findUnique ( {
332+ where : { email : filter [ 0 ] . email } ,
333+ } ) ;
334+
335+ if ( ! user ) {
336+ reply . send ( {
337+ success : false ,
338+ message : "Invalid email" ,
339+ } ) ;
340+ }
341+
342+ var b64string = process . env . SECRET ;
343+ var buf = new Buffer ( b64string ! , "base64" ) ; // Ta-da
344+
345+ let token = jwt . sign (
346+ {
347+ data : { id : user ! . id } ,
348+ } ,
349+ buf ,
350+ { expiresIn : "8h" }
351+ ) ;
352+
353+ await prisma . session . create ( {
354+ data : {
355+ userId : user ! . id ,
356+ sessionToken : token ,
357+ expires : new Date ( Date . now ( ) + 8 * 60 * 60 * 1000 ) ,
358+ } ,
359+ } ) ;
360+
361+ reply . send ( {
362+ token,
363+ success : true ,
364+ } ) ;
365+ } else {
366+ reply . status ( 403 ) . send ( {
367+ success : false ,
368+ } ) ;
369+ }
370+ }
371+ ) ;
372+
140373 // Delete a user
141374 fastify . delete (
142375 "/api/v1/auth/user/:id" ,
@@ -177,10 +410,12 @@ export function authRoutes(fastify: FastifyInstance) {
177410
178411 if ( ! user ) {
179412 reply . code ( 401 ) . send ( {
180- message : "Invalid email or password " ,
413+ message : "Invalid user " ,
181414 } ) ;
182415 }
183416
417+ const config = await prisma . config . findFirst ( ) ;
418+
184419 const data = {
185420 id : user ! . id ,
186421 email : user ! . email ,
@@ -191,6 +426,7 @@ export function authRoutes(fastify: FastifyInstance) {
191426 ticket_status_changed : user ! . notify_ticket_status_changed ,
192427 ticket_comments : user ! . notify_ticket_comments ,
193428 ticket_assigned : user ! . notify_ticket_assigned ,
429+ sso_status : config ! . sso_active ,
194430 } ;
195431
196432 reply . send ( {
@@ -282,6 +518,50 @@ export function authRoutes(fastify: FastifyInstance) {
282518 }
283519 ) ;
284520
521+ // Update a users Email notification settings
522+ fastify . put (
523+ "/api/v1/auth/profile/notifcations/emails" ,
524+ async ( request : FastifyRequest , reply : FastifyReply ) => {
525+ const bearer = request . headers . authorization ! . split ( " " ) [ 1 ] ;
526+
527+ //checks if token is valid and returns valid token
528+ const token = checkToken ( bearer ) ;
529+
530+ if ( token ) {
531+ let session = await prisma . session . findUnique ( {
532+ where : {
533+ sessionToken : bearer ,
534+ } ,
535+ } ) ;
536+
537+ const {
538+ notify_ticket_created,
539+ notify_ticket_assigned,
540+ notify_ticket_comments,
541+ notify_ticket_status_changed,
542+ } = request . body as any ;
543+
544+ let user = await prisma . user . update ( {
545+ where : { id : session ?. userId } ,
546+ data : {
547+ notify_ticket_created : notify_ticket_created ,
548+ notify_ticket_assigned : notify_ticket_assigned ,
549+ notify_ticket_comments : notify_ticket_comments ,
550+ notify_ticket_status_changed : notify_ticket_status_changed ,
551+ } ,
552+ } ) ;
553+
554+ reply . send ( {
555+ user,
556+ } ) ;
557+ } else {
558+ reply . send ( {
559+ sucess : false ,
560+ } ) ;
561+ }
562+ }
563+ ) ;
564+
285565 // Logout a user (deletes session)
286566 fastify . get (
287567 "/api/v1/auth/user/:id/logout" ,
@@ -299,4 +579,25 @@ export function authRoutes(fastify: FastifyInstance) {
299579 }
300580 }
301581 ) ;
582+
583+ // Update a users role
584+ fastify . put (
585+ "/api/v1/auth/user/role" ,
586+ async ( request : FastifyRequest , reply : FastifyReply ) => {
587+ const bearer = request . headers . authorization ! . split ( " " ) [ 1 ] ;
588+ const token = checkToken ( bearer ) ;
589+ if ( token ) {
590+ const { id, role } = request . body as { id : string ; role : boolean } ;
591+
592+ await prisma . user . update ( {
593+ where : { id } ,
594+ data : {
595+ isAdmin : role ,
596+ } ,
597+ } ) ;
598+
599+ reply . send ( { success : true } ) ;
600+ }
601+ }
602+ ) ;
302603}
0 commit comments