2
2
import 'reflect-metadata' ;
3
3
4
4
import dotenv from 'dotenv' ;
5
- import { createExpressServer , ForbiddenError , useContainer as routingUseContainer } from 'routing-controllers' ;
5
+ import { createExpressServer , ForbiddenError , UnauthorizedError , useContainer as routingUseContainer } from 'routing-controllers' ;
6
6
import { EntityManager , getManager , useContainer } from 'typeorm' ;
7
7
import { Container } from 'typeorm-typedi-extensions' ;
8
8
import { Express } from 'express' ;
@@ -12,7 +12,6 @@ import * as path from 'path';
12
12
import { controllers } from './api/controllers' ;
13
13
import { middlewares } from './api/middlewares' ;
14
14
import { UserModel } from './models/UserModel' ;
15
- import { UserSessionModel } from './models/UserSessionModel' ;
16
15
import { ReportPostRequest , ReportProfileRequest , ReportMessageRequest } from './types' ;
17
16
import { GetReportsResponse , Report } from './types/ApiResponses' ;
18
17
import { ReportController } from './api/controllers/ReportController' ;
@@ -21,9 +20,23 @@ import { ReportService } from './services/ReportService';
21
20
import { ReportRepository } from './repositories/ReportRepository' ;
22
21
import { reportToString } from './utils/Requests' ;
23
22
import { CurrentUserChecker } from 'routing-controllers/types/CurrentUserChecker' ;
23
+ import * as firebaseAdmin from 'firebase-admin' ;
24
+
24
25
25
26
dotenv . config ( ) ;
27
+ var serviceAccountPath = process . env . FIREBASE_SERVICE_ACCOUNT_PATH ! ;
28
+ const serviceAccount = require ( serviceAccountPath ) ;
29
+
26
30
31
+ if ( ! serviceAccountPath ) {
32
+ throw new Error ( 'FIREBASE_SERVICE_ACCOUNT_PATH environment variable is not set.' ) ;
33
+ }
34
+
35
+ // Initialize Firebase Admin SDK
36
+ export const admin = firebaseAdmin . initializeApp ( {
37
+ credential : firebaseAdmin . credential . cert ( serviceAccount ) ,
38
+ // databaseURL: "https://resell-e99a2-default-rtdb.firebaseio.com"
39
+ } ) ;
27
40
28
41
async function main ( ) {
29
42
routingUseContainer ( Container ) ;
@@ -40,18 +53,47 @@ async function main() {
40
53
controllers : controllers ,
41
54
middlewares : middlewares ,
42
55
currentUserChecker : async ( action : any ) => {
43
- const accessToken = action . request . headers [ "authorization" ] ;
44
- const manager = getManager ( ) ;
45
- // find the user who has a token in their sessions field
46
- const session = await manager . findOne ( UserSessionModel , { accessToken : accessToken } ) ;
47
- // check if the session token has expired
48
- if ( session && session . expiresAt . getTime ( ) > Date . now ( ) ) {
49
- const userId = session . userId ;
50
- // find a user with id `userId` and join with posts, saved,
51
- // sessions, feedbacks, and requests
52
- return await manager . findOne ( UserModel , { id : userId } , { relations : [ "posts" , "saved" , "sessions" , "feedbacks" , "requests" ] } ) ;
56
+ const authHeader = action . request . headers [ "authorization" ] ;
57
+ if ( ! authHeader ) {
58
+ throw new ForbiddenError ( "No authorization token provided" ) ;
59
+ }
60
+ const token = authHeader . split ( ' ' ) [ 1 ] ;
61
+ if ( ! token ) {
62
+ throw new ForbiddenError ( "Invalid authorization token format" ) ;
63
+ }
64
+ try {
65
+ // Verify the token using Firebase Admin SDK
66
+ const decodedToken = await admin . auth ( ) . verifyIdToken ( token ) ;
67
+ // Check if the email is a Cornell email
68
+ const email = decodedToken . email ;
69
+ const userId = decodedToken . uid ;
70
+ if ( ! email || ! email . endsWith ( '@cornell.edu' ) ) {
71
+ throw new ForbiddenError ( 'Only Cornell email addresses are allowed' ) ;
72
+ }
73
+ // Find or create user in your database using Firebase UID
74
+ const manager = getManager ( ) ;
75
+ let user = await manager . findOne ( UserModel , { firebaseUid : userId } ,
76
+ { relations : [ "posts" , "saved" , "feedbacks" , "requests" ] } ) ;
77
+ if ( ! user ) {
78
+ // Check if this is the user creation route
79
+ const isUserCreateRoute = action . request . path === '/api/user/create' || action . request . path === 'api/authorize' ;
80
+ if ( ! isUserCreateRoute ) {
81
+ throw new ForbiddenError ( 'User not found. Please create an account first.' ) ;
82
+ }
83
+ // For user creation routes, return a minimal UserModel
84
+ const tempUser = new UserModel ( ) ;
85
+ tempUser . googleId = email ;
86
+ tempUser . firebaseUid = decodedToken . uid ;
87
+ tempUser . isNewUser = true ;
88
+ return tempUser ;
89
+ }
90
+ return user ;
91
+ } catch ( error ) {
92
+ if ( error . code === 'auth/id-token-expired' ) {
93
+ throw new UnauthorizedError ( 'Token has expired' ) ;
94
+ }
95
+ throw new UnauthorizedError ( 'Invalid authorization token' ) ;
53
96
}
54
- throw new ForbiddenError ( "User unauthorized" ) ;
55
97
} ,
56
98
defaults : {
57
99
paramOptions : {
@@ -81,16 +123,29 @@ async function main() {
81
123
82
124
app . get ( '/api/reports/admin/' , async ( req : any , res : any ) => {
83
125
const userCheck = async ( action : any ) => {
84
- const accessToken = action . headers [ "authorization" ] ;
85
- const manager = getManager ( ) ;
86
- const session = await manager . findOne ( UserSessionModel , { accessToken : accessToken } ) ;
87
- if ( session && session . expiresAt . getTime ( ) > Date . now ( ) ) {
88
- const userId = session . userId ;
89
- const user = await manager . findOne ( UserModel , { id : userId } , { relations : [ "posts" , "saved" , "sessions" , "feedbacks" , "requests" ] } ) ;
126
+ const authHeader = action . request . headers [ "authorization" ] ;
127
+ if ( ! authHeader ) {
128
+ throw new ForbiddenError ( "No authorization token provided" ) ;
129
+ }
130
+ const token = authHeader . split ( ' ' ) [ 1 ] ;
131
+ if ( ! token ) {
132
+ throw new ForbiddenError ( "Invalid authorization token format" ) ;
133
+ }
134
+ try {
135
+ // Verify the token using Firebase Admin SDK
136
+ const decodedToken = await admin . auth ( ) . verifyIdToken ( token ) ;
137
+ const userId = decodedToken . uid ;
138
+ // Find or create user in your database using Firebase UID
139
+ const manager = getManager ( ) ;
140
+ const user = await manager . findOne ( UserModel , { firebaseUid : userId } ) ;
90
141
if ( ! user || ! user . admin ) throw new ForbiddenError ( "User unauthorized" ) ;
91
142
return user ;
143
+ } catch ( error ) {
144
+ if ( error . code === 'auth/id-token-expired' ) {
145
+ throw new UnauthorizedError ( 'Token has expired' ) ;
146
+ }
147
+ throw new UnauthorizedError ( 'Invalid authorization token' ) ;
92
148
}
93
- throw new ForbiddenError ( "User unauthorized" ) ;
94
149
}
95
150
const user = await userCheck ( req ) ;
96
151
user . admin = true ;
0 commit comments