{"version":3,"file":"authMiddleware-DPly0b_T.mjs","names":[],"sources":["../src/middleware/authMiddleware.ts"],"sourcesContent":["import { createMiddleware } from \"@tanstack/react-start\";\nimport * as jose from \"jose\";\nimport type { permissions } from \"virtual:wcz-layout\";\nimport { serverEnv } from \"~/env\";\nimport { getSessionUser } from \"~/lib/auth/user\";\nimport { buildUser, hasPermission } from \"~/lib/utils\";\nimport type { TokenPayload } from \"~/models/TokenPayload\";\nimport type { User } from \"~/models/User\";\n\nasync function resolveUser(request: Request): Promise<User | null> {\n  const authHeader = request.headers.get(\"Authorization\");\n\n  if (authHeader?.startsWith(\"Bearer \")) {\n    let payload: TokenPayload;\n    try {\n      payload = await verifyToken(authHeader.substring(\"Bearer \".length));\n    } catch (error) {\n      throw Response.json(\n        { message: error instanceof Error ? error.message : \"Unauthorized: Invalid access token\" },\n        { status: 401 },\n      );\n    }\n    return buildUser(payload);\n  }\n\n  return getSessionUser();\n}\n\nconst requiredAuthenticationMiddleware = createMiddleware().server<{ user: User }>(\n  async ({ next, request }) => {\n    const user = await resolveUser(request);\n\n    if (!user)\n      throw Response.json({ message: \"Unauthorized: User not signed in\" }, { status: 401 });\n\n    return next({ context: { user } });\n  },\n);\n\nconst publicAuthenticationMiddleware = createMiddleware().server<{ user: User | null }>(\n  async ({ next, request }) => {\n    const user = await resolveUser(request);\n    return next({ context: { user } });\n  },\n);\n\nexport function authenticationMiddleware(options?: {\n  optional?: false;\n}): typeof requiredAuthenticationMiddleware;\n\nexport function authenticationMiddleware(options: {\n  optional: true;\n}): typeof publicAuthenticationMiddleware;\n\nexport function authenticationMiddleware(options: {\n  optional: boolean;\n}): typeof requiredAuthenticationMiddleware | typeof publicAuthenticationMiddleware;\n\nexport function authenticationMiddleware(options?: { optional?: boolean }) {\n  return options?.optional ? publicAuthenticationMiddleware : requiredAuthenticationMiddleware;\n}\n\nexport const authorizationMiddleware = (permissionKey: keyof typeof permissions) =>\n  createMiddleware()\n    .middleware([authenticationMiddleware()])\n    .server(async ({ next, context }) => {\n      if (hasPermission(context.user, permissionKey)) return next();\n      throw Response.json(\n        {\n          message: `Forbidden: User ${context.user.name} is not authorized to access this resource`,\n        },\n        { status: 403 },\n      );\n    });\n\nasync function verifyToken(token: string): Promise<TokenPayload> {\n  const { payload } = await jose.jwtVerify(token, getJWKS(), {\n    issuer: `https://login.microsoftonline.com/${serverEnv.ENTRA_TENANT_ID}/v2.0`,\n    audience: serverEnv.ENTRA_CLIENT_ID,\n  });\n  return payload as unknown as TokenPayload;\n}\n\nlet jwksCache: ReturnType<typeof jose.createRemoteJWKSet> | null = null;\n\nfunction getJWKS() {\n  jwksCache ??= jose.createRemoteJWKSet(\n    new URL(`https://login.microsoftonline.com/${serverEnv.ENTRA_TENANT_ID}/discovery/v2.0/keys`),\n  );\n  return jwksCache;\n}\n"],"mappings":";;;;AASA,eAAe,YAAY,SAAwC;CACjE,MAAM,aAAa,QAAQ,QAAQ,IAAI,eAAe;CAEtD,IAAI,YAAY,WAAW,SAAS,GAAG;EACrC,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,YAAY,WAAW,UAAU,CAAgB,CAAC;EACpE,SAAS,OAAO;GACd,MAAM,SAAS,KACb,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,qCAAqC,GACzF,EAAE,QAAQ,IAAI,CAChB;EACF;EACA,OAAO,UAAU,OAAO;CAC1B;CAEA,OAAO,eAAe;AACxB;AAEA,MAAM,mCAAmC,iBAAiB,CAAC,CAAC,OAC1D,OAAO,EAAE,MAAM,cAAc;CAC3B,MAAM,OAAO,MAAM,YAAY,OAAO;CAEtC,IAAI,CAAC,MACH,MAAM,SAAS,KAAK,EAAE,SAAS,mCAAmC,GAAG,EAAE,QAAQ,IAAI,CAAC;CAEtF,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACnC,CACF;AAEA,MAAM,iCAAiC,iBAAiB,CAAC,CAAC,OACxD,OAAO,EAAE,MAAM,cAAc;CAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAA,MADN,YAAY,OAAO,EACR,EAAE,CAAC;AACnC,CACF;AAcA,SAAgB,yBAAyB,SAAkC;CACzE,OAAO,SAAS,WAAW,iCAAiC;AAC9D;AAEA,MAAa,2BAA2B,kBACtC,iBAAiB,CAAC,CACf,WAAW,CAAC,yBAAyB,CAAC,CAAC,CAAC,CACxC,OAAO,OAAO,EAAE,MAAM,cAAc;CACnC,IAAI,cAAc,QAAQ,MAAM,aAAa,GAAG,OAAO,KAAK;CAC5D,MAAM,SAAS,KACb,EACE,SAAS,mBAAmB,QAAQ,KAAK,KAAI,4CAC/C,GACA,EAAE,QAAQ,IAAI,CAChB;AACF,CAAC;AAEL,eAAe,YAAY,OAAsC;CAC/D,MAAM,EAAE,YAAY,MAAM,KAAK,UAAU,OAAO,QAAQ,GAAG;EACzD,QAAQ,qCAAqC,UAAU,gBAAe;EACtE,UAAU,UAAU;CACtB,CAAC;CACD,OAAO;AACT;AAEA,IAAI,YAA+D;AAEnE,SAAS,UAAU;CACjB,cAAc,KAAK,mBACjB,IAAI,IAAI,qCAAqC,UAAU,gBAAe,qBAAsB,CAC9F;CACA,OAAO;AACT"}