📦 EqualifyEverything / equalify

📄 index.ts · 97 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97import { router, event, setEvent, logEvent, verifySsoToken, ensureSsoUser } from '#src/utils';
import * as authRoutes from "./auth";
import { postConfirmationConfirmSignUp, preSignUpSignUp, tokenGeneration } from "./cognito";
import * as internalRoutes from "./internal";
import * as publicRoutes from "./public";
import * as scheduledRoutes from "./scheduled";
import * as hasuraRoutes from "./hasura";
import { CognitoJwtVerifier } from "aws-jwt-verify";
const verifier = CognitoJwtVerifier.create({ userPoolId: process.env.USER_POOL_ID, tokenUse: "id", clientId: process.env.WEB_CLIENT_ID });

export const authRouter = async () => {
    try {
        if (process.env.SSO_ENABLED) {
            const rawClaims: any = await verifySsoToken(event.headers.authorization.replace('Bearer ', ''));
            
            // Ensure SSO user exists in DB and get normalized claims + Hasura claims
            try {
                const { normalizedClaims, hasuraClaims } = await ensureSsoUser(rawClaims);
                
                // Add Hasura claims to the normalized claims (matches Cognito structure)
                const enrichedClaims = {
                    ...normalizedClaims,
                    'https://hasura.io/jwt/claims': hasuraClaims,
                };
                
                const updatedEvent = setEvent({ ...event, claims: enrichedClaims });
                logEvent(updatedEvent);
            } catch (ensureUserErr) {
                // User is authenticated with SSO but not authorized to use Equalify
                console.log('User authorization failed:', ensureUserErr);
                return {
                    statusCode: 403,
                    body: JSON.stringify({ 
                        error: 'Forbidden', 
                        message: ensureUserErr.message 
                    }),
                    headers: { 'Content-Type': 'application/json' }
                };
            }
        }
        else {
            const claims = await verifier.verify(event.headers.authorization.replace('Bearer ', ''));
            const updatedEvent = setEvent({ ...event, claims });
            logEvent(updatedEvent);
        }
        return router(authRoutes);
    }
    catch (err) {
        console.log(err);
        return {
            statusCode: 401,
            body: JSON.stringify({ 
                error: 'Unauthorized', 
                message: 'Your authorization token is invalid' 
            }),
            headers: { 'Content-Type': 'application/json' }
        };
    }
}

export const cognitoRouter = async () => {
    logEvent(event);
    if (event.triggerSource === "PreSignUp_SignUp") {
        return preSignUpSignUp();
    }
    else if (event.triggerSource === "PostConfirmation_ConfirmSignUp") {
        return postConfirmationConfirmSignUp();
    }
    else if (['TokenGeneration_Authentication', 'TokenGeneration_RefreshTokens', 'TokenGeneration_AuthenticateDevice'].includes(event.triggerSource)) {
        return tokenGeneration();
    }
    else {
        return event;
    }
}

export const internalRouter = async () => {
    logEvent(event);
    return router(internalRoutes);
}

export const publicRouter = async () => {
    logEvent(event);
    return router(publicRoutes);
}

export const scheduledRouter = async () => {
    logEvent(event);
    return router(scheduledRoutes);
}

export const hasuraRouter = async () => {
    logEvent(event);
    if (event.headers.webhooksecret === process.env.WEBHOOKSECRET) {
        return router(hasuraRoutes);
    }
}