import { APIGatewayEvent } from 'aws-lambda' import { HttpError } from './error' import jwt from 'jsonwebtoken' import { firebaseApp } from 'services/firebase/firebase' import { getOrganization } from 'services/organization' export type Role = 'admin' | 'user' | 'organization' export type Authorization = { userEmail?: string organizationIdentity?: string role: Role } export const authorize = async (event: APIGatewayEvent): Promise => { const authorization = event.headers['Authorization'] || event.headers['authorization'] if (!authorization) { throw new HttpError(401, 'Unauthorized') } if (!process.env.JWT_SECRET) { throw new Error('JWT_SECRET is not defined') } const [scheme, token] = authorization.split(' ') if (scheme !== 'Bearer') { throw new HttpError(401, 'Authorization scheme not supported') } try { const verified = jwt.verify(token, process.env.JWT_SECRET) const { userEmail, organizationIdentity: organizationId, role } = verified as Authorization return { userEmail, organizationIdentity: organizationId, role } } catch { try { const idToken = await firebaseApp.auth().verifyIdToken(token) if (!idToken.email) { throw new HttpError(401, 'Unauthorized') } let email = idToken.email const role = idToken.email?.endsWith('@copykit.com.br') ? 'admin' : 'user' if (role === 'admin' && event.headers['x-delegated-user']) { email = event.headers['x-delegated-user'] } return { userEmail: email, role, } } catch { throw new HttpError(401, 'Invalid token') } } } export const createOrganizationAuth = async ( organizationIdentity: string, accessKey: string, userEmail?: string, ): Promise => { if (!process.env.JWT_SECRET) { throw new Error('JWT_SECRET is not defined') } const authorization: Authorization = { organizationIdentity: organizationIdentity, userEmail, role: 'organization', } const organization = await getOrganization(organizationIdentity) if (!organization) { throw new HttpError(404, 'Organization not found') } if (organization.accessKey !== accessKey) { throw new HttpError(401, 'Invalid access key') } const token = jwt.sign(authorization, process.env.JWT_SECRET) return token }