@rpcbase/auth 0.123.0 → 0.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/me/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBAkDlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAGC"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/me/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA4DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAGC"}
@@ -0,0 +1,5 @@
1
+ import { Api } from '@rpcbase/api';
2
+ import { AuthSessionUser } from '../../types';
3
+ declare const _default: (api: Api<AuthSessionUser>) => void;
4
+ export default _default;
5
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/set-active-account/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBAqDlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAGC"}
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ export declare const Route = "/api/rb/auth/set-active-account";
3
+ export declare const requestSchema: z.ZodObject<{
4
+ tenantId: z.ZodString;
5
+ }, z.core.$strip>;
6
+ export type RequestPayload = z.infer<typeof requestSchema>;
7
+ export declare const responseSchema: z.ZodObject<{
8
+ success: z.ZodBoolean;
9
+ error: z.ZodOptional<z.ZodString>;
10
+ tenantId: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ export type ResponsePayload = z.infer<typeof responseSchema>;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/set-active-account/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,KAAK,oCAAoC,CAAA;AAEtD,eAAO,MAAM,aAAa;;iBAExB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAE1D,eAAO,MAAM,cAAc;;;;iBAIzB,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/sign-in/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA2DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/sign-in/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAKnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA6DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/verify-otp/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA6DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/verify-otp/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA+DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
@@ -1,5 +1,6 @@
1
1
  import { models } from "@rpcbase/db";
2
2
  import { verifyPasswordFromStorage } from "@rpcbase/server";
3
+ import { c as completeAuthSignIn } from "./session-DoTNxRRA.js";
3
4
  import { R as Route, r as requestSchema } from "./index-Bxz6YdiB.js";
4
5
  const signIn = async (payload, ctx) => {
5
6
  const User = await models.getGlobal("RBUser", ctx);
@@ -41,24 +42,30 @@ const signIn = async (payload, ctx) => {
41
42
  error: "invalid_credentials"
42
43
  };
43
44
  }
44
- const tenantId = user.tenants?.[0]?.toString?.() || "00000000";
45
45
  const signedInTenants = (user.tenants || []).map(String);
46
- const tenantRolesMap = user.get("tenantRoles");
47
- const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : void 0;
48
- if (!ctx.req.session) {
46
+ const defaultTenantId = signedInTenants[0];
47
+ if (!defaultTenantId) {
49
48
  ctx.res.status(500);
50
49
  return {
51
50
  success: false,
52
- error: "session_unavailable"
51
+ error: "tenant_unavailable"
53
52
  };
54
53
  }
55
- ctx.req.session.user = {
56
- id: user._id.toString(),
54
+ const tenantId = defaultTenantId;
55
+ const tenantRolesMap = user.get("tenantRoles");
56
+ const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : void 0;
57
+ if (!completeAuthSignIn(ctx, {
58
+ userId: user._id.toString(),
57
59
  currentTenantId: tenantId,
58
60
  signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],
59
- isEntryGateAuthorized: true,
60
61
  tenantRoles
61
- };
62
+ })) {
63
+ ctx.res.status(500);
64
+ return {
65
+ success: false,
66
+ error: "session_unavailable"
67
+ };
68
+ }
62
69
  return {
63
70
  success: true,
64
71
  userId: user._id.toString(),
@@ -71,4 +78,4 @@ const handler = (api) => {
71
78
  export {
72
79
  handler as default
73
80
  };
74
- //# sourceMappingURL=handler-DfEsSB4T.js.map
81
+ //# sourceMappingURL=handler-B5I4pH46.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler-B5I4pH46.js","sources":["../src/api/sign-in/handler.ts"],"sourcesContent":["import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\nimport { verifyPasswordFromStorage } from \"@rpcbase/server\"\n\nimport { completeAuthSignIn } from \"../../session\"\nimport type { AuthSessionUser } from \"../../types\"\n\nimport * as SignIn from \"./index\"\n\n\nconst signIn: ApiHandler<SignIn.RequestPayload, SignIn.ResponsePayload, AuthSessionUser> = async(\n payload,\n ctx: Ctx<AuthSessionUser>\n): Promise<SignIn.ResponsePayload> => {\n const User = await models.getGlobal(\"RBUser\", ctx)\n\n const parsed = SignIn.requestSchema.safeParse(payload)\n\n if (!parsed.success) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_payload\" }\n }\n\n const { email, password } = parsed.data\n\n const user = await User.findOne({ email }, { password: 1, tenants: 1, tenantRoles: 1 })\n\n if (!user?.password) {\n ctx.res.status(401)\n return { success: false, error: \"invalid_credentials\" }\n }\n\n const stored = String(user.password)\n const passwordMatches = await verifyPasswordFromStorage(password, stored)\n\n if (!passwordMatches) {\n if (!stored.startsWith(\"$scrypt$\")) {\n console.warn(\"auth::sign-in invalid stored password format\", user._id.toString())\n }\n ctx.res.status(401)\n return { success: false, error: \"invalid_credentials\" }\n }\n\n const signedInTenants = (user.tenants || []).map(String)\n const defaultTenantId = signedInTenants[0]\n if (!defaultTenantId) {\n ctx.res.status(500)\n return { success: false, error: \"tenant_unavailable\" }\n }\n const tenantId = defaultTenantId\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!completeAuthSignIn(ctx, {\n userId: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n tenantRoles,\n })) {\n ctx.res.status(500)\n return { success: false, error: \"session_unavailable\" }\n }\n\n return { success: true, userId: user._id.toString(), tenantId }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.post(SignIn.Route, signIn)\n}\n"],"names":["signIn","payload","ctx","User","models","getGlobal","parsed","SignIn","safeParse","success","res","status","error","email","password","data","user","findOne","tenants","tenantRoles","stored","String","passwordMatches","verifyPasswordFromStorage","startsWith","console","warn","_id","toString","signedInTenants","map","defaultTenantId","tenantId","tenantRolesMap","get","Object","fromEntries","entries","undefined","completeAuthSignIn","userId","currentTenantId","length","api","post"],"mappings":";;;;AAUA,MAAMA,SAAqF,OACzFC,SACAC,QACoC;AACpC,QAAMC,OAAO,MAAMC,OAAOC,UAAU,UAAUH,GAAG;AAEjD,QAAMI,SAASC,cAAqBC,UAAUP,OAAO;AAErD,MAAI,CAACK,OAAOG,SAAS;AACnBP,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAM;AAAA,IAAEC;AAAAA,IAAOC;AAAAA,EAAAA,IAAaR,OAAOS;AAEnC,QAAMC,OAAO,MAAMb,KAAKc,QAAQ;AAAA,IAAEJ;AAAAA,EAAAA,GAAS;AAAA,IAAEC,UAAU;AAAA,IAAGI,SAAS;AAAA,IAAGC,aAAa;AAAA,EAAA,CAAG;AAEtF,MAAI,CAACH,MAAMF,UAAU;AACnBZ,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMQ,SAASC,OAAOL,KAAKF,QAAQ;AACnC,QAAMQ,kBAAkB,MAAMC,0BAA0BT,UAAUM,MAAM;AAExE,MAAI,CAACE,iBAAiB;AACpB,QAAI,CAACF,OAAOI,WAAW,UAAU,GAAG;AAClCC,cAAQC,KAAK,gDAAgDV,KAAKW,IAAIC,UAAU;AAAA,IAClF;AACA1B,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMiB,mBAAmBb,KAAKE,WAAW,CAAA,GAAIY,IAAIT,MAAM;AACvD,QAAMU,kBAAkBF,gBAAgB,CAAC;AACzC,MAAI,CAACE,iBAAiB;AACpB7B,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AACA,QAAMoB,WAAWD;AACjB,QAAME,iBAAiBjB,KAAKkB,IAAI,aAAa;AAC7C,QAAMf,cAAcc,iBAAiBE,OAAOC,YAAYH,eAAeI,QAAAA,CAAS,IAAIC;AAEpF,MAAI,CAACC,mBAAmBrC,KAAK;AAAA,IAC3BsC,QAAQxB,KAAKW,IAAIC,SAAAA;AAAAA,IACjBa,iBAAiBT;AAAAA,IACjBH,iBAAiBA,gBAAgBa,SAASb,kBAAkB,CAACG,QAAQ;AAAA,IACrEb;AAAAA,EAAAA,CACD,GAAG;AACFjB,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,SAAO;AAAA,IAAEH,SAAS;AAAA,IAAM+B,QAAQxB,KAAKW,IAAIC,SAAAA;AAAAA,IAAYI;AAAAA,EAAAA;AACvD;AAEA,MAAA,UAAe,CAACW,QAA8B;AAC5CA,MAAIC,KAAKrC,OAAcP,MAAM;AAC/B;"}
@@ -37,7 +37,17 @@ const me = async (_payload, ctx) => {
37
37
  error: "user_not_found"
38
38
  };
39
39
  }
40
- const tenantId = sessionUser.currentTenantId || user.tenants?.[0]?.toString?.() || "00000000";
40
+ const tenantId = typeof sessionUser.currentTenantId === "string" ? sessionUser.currentTenantId.trim() : "";
41
+ if (!tenantId) {
42
+ ctx.res.status(500);
43
+ return {
44
+ id: "",
45
+ currentTenantId: "",
46
+ signedInTenants: [],
47
+ tenants: [],
48
+ error: "tenant_missing"
49
+ };
50
+ }
41
51
  return {
42
52
  id: user._id.toString(),
43
53
  email: user.email,
@@ -55,4 +65,4 @@ const handler = (api) => {
55
65
  export {
56
66
  handler as default
57
67
  };
58
- //# sourceMappingURL=handler-D7KnXlx3.js.map
68
+ //# sourceMappingURL=handler-CbSJDqWW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler-CbSJDqWW.js","sources":["../src/api/me/index.ts","../src/api/me/handler.ts"],"sourcesContent":["import { z } from \"zod\"\n\n\nexport const Route = \"/api/rb/auth/me\"\n\nexport const requestSchema = z.object({})\nexport type RequestPayload = z.infer<typeof requestSchema>\n\nexport const responseSchema = z.object({\n id: z.string().optional(),\n email: z.string().email().optional(),\n phone: z.string().optional(),\n name: z.string().optional(),\n tenants: z.array(z.string()).default([]),\n currentTenantId: z.string().optional(),\n signedInTenants: z.array(z.string()).default([]).optional(),\n error: z.string().optional(),\n})\n\nexport type ResponsePayload = z.infer<typeof responseSchema>\n","import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\n\nimport type { AuthSessionUser } from \"../../types\"\nimport { restrictSessionMiddleware } from \"../../middleware\"\n\nimport * as Me from \"./index\"\n\n\nconst me: ApiHandler<Me.RequestPayload, Me.ResponsePayload, AuthSessionUser> = async(\n _payload: Me.RequestPayload,\n ctx: Ctx<AuthSessionUser>\n): Promise<Me.ResponsePayload> => {\n const sessionUser = ctx.req.session?.user\n\n if (!sessionUser?.id) {\n ctx.res.status(401)\n return {\n id: \"\",\n currentTenantId: \"\",\n signedInTenants: [],\n tenants: [],\n error: \"not_authenticated\",\n } as unknown as Me.ResponsePayload\n }\n\n const User = await models.getGlobal(\"RBUser\", ctx)\n const user = await User.findById(sessionUser.id)\n\n if (!user) {\n ctx.res.status(404)\n return {\n id: \"\",\n currentTenantId: \"\",\n signedInTenants: [],\n tenants: [],\n error: \"user_not_found\",\n } as unknown as Me.ResponsePayload\n }\n\n const tenantId = typeof sessionUser.currentTenantId === \"string\" ? sessionUser.currentTenantId.trim() : \"\"\n if (!tenantId) {\n ctx.res.status(500)\n return {\n id: \"\",\n currentTenantId: \"\",\n signedInTenants: [],\n tenants: [],\n error: \"tenant_missing\",\n } as unknown as Me.ResponsePayload\n }\n\n return {\n id: user._id.toString(),\n email: user.email,\n phone: user.get(\"phone\") as string | undefined,\n name: user.name,\n tenants: (user.tenants || []).map(String),\n currentTenantId: tenantId,\n signedInTenants: sessionUser.signedInTenants || [],\n }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.use(Me.Route, restrictSessionMiddleware)\n api.get(Me.Route, me)\n}\n"],"names":["Route","z","id","string","optional","email","phone","name","tenants","default","currentTenantId","signedInTenants","error","me","_payload","ctx","sessionUser","req","session","user","res","status","User","models","getGlobal","findById","tenantId","trim","_id","toString","get","map","String","api","use","Me","restrictSessionMiddleware"],"mappings":";;;AAGO,MAAMA,QAAQ;AAEQC,OAAS,CAAA,CAAE;AAGVA,OAAS;AAAA,EACrCC,IAAID,OAAEE,EAASC,SAAAA;AAAAA,EACfC,OAAOJ,OAAEE,EAASE,MAAAA,EAAQD,SAAAA;AAAAA,EAC1BE,OAAOL,OAAEE,EAASC,SAAAA;AAAAA,EAClBG,MAAMN,OAAEE,EAASC,SAAAA;AAAAA,EACjBI,SAASP,MAAQA,QAAU,EAAEQ,QAAQ,CAAA,CAAE;AAAA,EACvCC,iBAAiBT,OAAEE,EAASC,SAAAA;AAAAA,EAC5BO,iBAAiBV,MAAQA,OAAEE,CAAQ,EAAEM,QAAQ,CAAA,CAAE,EAAEL,SAAAA;AAAAA,EACjDQ,OAAOX,OAAEE,EAASC,SAAAA;AACpB,CAAC;ACRD,MAAMS,KAAyE,OAC7EC,UACAC,QACgC;AAChC,QAAMC,cAAcD,IAAIE,IAAIC,SAASC;AAErC,MAAI,CAACH,aAAad,IAAI;AACpBa,QAAIK,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MACLnB,IAAI;AAAA,MACJQ,iBAAiB;AAAA,MACjBC,iBAAiB,CAAA;AAAA,MACjBH,SAAS,CAAA;AAAA,MACTI,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,QAAMU,OAAO,MAAMC,OAAOC,UAAU,UAAUT,GAAG;AACjD,QAAMI,OAAO,MAAMG,KAAKG,SAAST,YAAYd,EAAE;AAE/C,MAAI,CAACiB,MAAM;AACTJ,QAAIK,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MACLnB,IAAI;AAAA,MACJQ,iBAAiB;AAAA,MACjBC,iBAAiB,CAAA;AAAA,MACjBH,SAAS,CAAA;AAAA,MACTI,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,QAAMc,WAAW,OAAOV,YAAYN,oBAAoB,WAAWM,YAAYN,gBAAgBiB,SAAS;AACxG,MAAI,CAACD,UAAU;AACbX,QAAIK,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MACLnB,IAAI;AAAA,MACJQ,iBAAiB;AAAA,MACjBC,iBAAiB,CAAA;AAAA,MACjBH,SAAS,CAAA;AAAA,MACTI,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,SAAO;AAAA,IACLV,IAAIiB,KAAKS,IAAIC,SAAAA;AAAAA,IACbxB,OAAOc,KAAKd;AAAAA,IACZC,OAAOa,KAAKW,IAAI,OAAO;AAAA,IACvBvB,MAAMY,KAAKZ;AAAAA,IACXC,UAAUW,KAAKX,WAAW,CAAA,GAAIuB,IAAIC,MAAM;AAAA,IACxCtB,iBAAiBgB;AAAAA,IACjBf,iBAAiBK,YAAYL,mBAAmB,CAAA;AAAA,EAAA;AAEpD;AAEA,MAAA,UAAe,CAACsB,QAA8B;AAC5CA,MAAIC,IAAIC,OAAUC,yBAAyB;AAC3CH,MAAIH,IAAIK,OAAUtB,EAAE;AACtB;"}
@@ -0,0 +1,66 @@
1
+ import { b as restrictSessionMiddleware } from "./middleware-8IfSkEEy.js";
2
+ import { A as AUTHENTICATED_TENANT_ID_HEADER } from "./session-DoTNxRRA.js";
3
+ import { o as object, s as string, b as boolean } from "./schemas-Dn3gHDGz.js";
4
+ const Route = "/api/rb/auth/set-active-account";
5
+ const requestSchema = object({
6
+ tenantId: string().min(1, "Tenant is required")
7
+ });
8
+ object({
9
+ success: boolean(),
10
+ error: string().optional(),
11
+ tenantId: string().optional()
12
+ });
13
+ const setActiveAccount = async (payload, ctx) => {
14
+ const parsed = requestSchema.safeParse(payload);
15
+ if (!parsed.success) {
16
+ ctx.res.status(400);
17
+ return {
18
+ success: false,
19
+ error: "invalid_payload"
20
+ };
21
+ }
22
+ const sessionUser = ctx.req.session?.user;
23
+ if (!sessionUser?.id) {
24
+ ctx.res.status(401);
25
+ return {
26
+ success: false,
27
+ error: "unauthorized"
28
+ };
29
+ }
30
+ const tenantId = parsed.data.tenantId.trim();
31
+ const signedInTenants = Array.isArray(sessionUser.signedInTenants) ? sessionUser.signedInTenants.map(String) : [];
32
+ if (signedInTenants.length > 0 && !signedInTenants.includes(tenantId)) {
33
+ ctx.res.status(403);
34
+ return {
35
+ success: false,
36
+ error: "invalid_account"
37
+ };
38
+ }
39
+ if (signedInTenants.length === 0) {
40
+ const currentTenantId = typeof sessionUser.currentTenantId === "string" ? sessionUser.currentTenantId.trim() : "";
41
+ if (!currentTenantId || currentTenantId !== tenantId) {
42
+ ctx.res.status(403);
43
+ return {
44
+ success: false,
45
+ error: "invalid_account"
46
+ };
47
+ }
48
+ }
49
+ ctx.req.session.user = {
50
+ ...sessionUser,
51
+ currentTenantId: tenantId
52
+ };
53
+ ctx.res.setHeader(AUTHENTICATED_TENANT_ID_HEADER, tenantId);
54
+ return {
55
+ success: true,
56
+ tenantId
57
+ };
58
+ };
59
+ const handler = (api) => {
60
+ api.use(Route, restrictSessionMiddleware);
61
+ api.post(Route, setActiveAccount);
62
+ };
63
+ export {
64
+ handler as default
65
+ };
66
+ //# sourceMappingURL=handler-VH4B70Zr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler-VH4B70Zr.js","sources":["../src/api/set-active-account/index.ts","../src/api/set-active-account/handler.ts"],"sourcesContent":["import { z } from \"zod\"\n\n\nexport const Route = \"/api/rb/auth/set-active-account\"\n\nexport const requestSchema = z.object({\n tenantId: z.string().min(1, \"Tenant is required\"),\n})\n\nexport type RequestPayload = z.infer<typeof requestSchema>\n\nexport const responseSchema = z.object({\n success: z.boolean(),\n error: z.string().optional(),\n tenantId: z.string().optional(),\n})\n\nexport type ResponsePayload = z.infer<typeof responseSchema>\n","import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\n\nimport { restrictSessionMiddleware } from \"../../middleware\"\nimport { AUTHENTICATED_TENANT_ID_HEADER } from \"../../session\"\nimport type { AuthSessionUser } from \"../../types\"\n\nimport * as SetActiveAccount from \"./index\"\n\n\nconst setActiveAccount: ApiHandler<\n SetActiveAccount.RequestPayload,\n SetActiveAccount.ResponsePayload,\n AuthSessionUser\n> = async(\n payload,\n ctx: Ctx<AuthSessionUser>\n): Promise<SetActiveAccount.ResponsePayload> => {\n const parsed = SetActiveAccount.requestSchema.safeParse(payload)\n\n if (!parsed.success) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_payload\" }\n }\n\n const sessionUser = ctx.req.session?.user\n if (!sessionUser?.id) {\n ctx.res.status(401)\n return { success: false, error: \"unauthorized\" }\n }\n\n const tenantId = parsed.data.tenantId.trim()\n const signedInTenants = Array.isArray(sessionUser.signedInTenants)\n ? sessionUser.signedInTenants.map(String)\n : []\n\n if (signedInTenants.length > 0 && !signedInTenants.includes(tenantId)) {\n ctx.res.status(403)\n return { success: false, error: \"invalid_account\" }\n }\n\n if (signedInTenants.length === 0) {\n const currentTenantId = typeof sessionUser.currentTenantId === \"string\" ? sessionUser.currentTenantId.trim() : \"\"\n if (!currentTenantId || currentTenantId !== tenantId) {\n ctx.res.status(403)\n return { success: false, error: \"invalid_account\" }\n }\n }\n\n ctx.req.session.user = {\n ...sessionUser,\n currentTenantId: tenantId,\n }\n ctx.res.setHeader(AUTHENTICATED_TENANT_ID_HEADER, tenantId)\n\n return { success: true, tenantId }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.use(SetActiveAccount.Route, restrictSessionMiddleware)\n api.post(SetActiveAccount.Route, setActiveAccount)\n}\n"],"names":["Route","requestSchema","z","tenantId","string","min","success","boolean","error","optional","setActiveAccount","payload","ctx","parsed","SetActiveAccount","safeParse","res","status","sessionUser","req","session","user","id","data","trim","signedInTenants","Array","isArray","map","String","length","includes","currentTenantId","setHeader","AUTHENTICATED_TENANT_ID_HEADER","api","use","restrictSessionMiddleware","post"],"mappings":";;;AAGO,MAAMA,QAAQ;AAEd,MAAMC,gBAAgBC,OAAS;AAAA,EACpCC,UAAUD,OAAEE,EAASC,IAAI,GAAG,oBAAoB;AAClD,CAAC;AAI6BH,OAAS;AAAA,EACrCI,SAASJ,QAAEK;AAAAA,EACXC,OAAON,OAAEE,EAASK,SAAAA;AAAAA,EAClBN,UAAUD,OAAEE,EAASK,SAAAA;AACvB,CAAC;ACND,MAAMC,mBAIF,OACFC,SACAC,QAC8C;AAC9C,QAAMC,SAASC,cAA+BC,UAAUJ,OAAO;AAE/D,MAAI,CAACE,OAAOP,SAAS;AACnBM,QAAII,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEX,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMU,cAAcN,IAAIO,IAAIC,SAASC;AACrC,MAAI,CAACH,aAAaI,IAAI;AACpBV,QAAII,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEX,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAML,WAAWU,OAAOU,KAAKpB,SAASqB,KAAAA;AACtC,QAAMC,kBAAkBC,MAAMC,QAAQT,YAAYO,eAAe,IAC7DP,YAAYO,gBAAgBG,IAAIC,MAAM,IACtC,CAAA;AAEJ,MAAIJ,gBAAgBK,SAAS,KAAK,CAACL,gBAAgBM,SAAS5B,QAAQ,GAAG;AACrES,QAAII,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEX,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,MAAIiB,gBAAgBK,WAAW,GAAG;AAChC,UAAME,kBAAkB,OAAOd,YAAYc,oBAAoB,WAAWd,YAAYc,gBAAgBR,SAAS;AAC/G,QAAI,CAACQ,mBAAmBA,oBAAoB7B,UAAU;AACpDS,UAAII,IAAIC,OAAO,GAAG;AAClB,aAAO;AAAA,QAAEX,SAAS;AAAA,QAAOE,OAAO;AAAA,MAAA;AAAA,IAClC;AAAA,EACF;AAEAI,MAAIO,IAAIC,QAAQC,OAAO;AAAA,IACrB,GAAGH;AAAAA,IACHc,iBAAiB7B;AAAAA,EAAAA;AAEnBS,MAAII,IAAIiB,UAAUC,gCAAgC/B,QAAQ;AAE1D,SAAO;AAAA,IAAEG,SAAS;AAAA,IAAMH;AAAAA,EAAAA;AAC1B;AAEA,MAAA,UAAe,CAACgC,QAA8B;AAC5CA,MAAIC,IAAItB,OAAwBuB,yBAAyB;AACzDF,MAAIG,KAAKxB,OAAwBJ,gBAAgB;AACnD;"}
@@ -1,4 +1,5 @@
1
1
  import { models } from "@rpcbase/db";
2
+ import { c as completeAuthSignIn } from "./session-DoTNxRRA.js";
2
3
  import { o as object, b as boolean, s as string } from "./schemas-Dn3gHDGz.js";
3
4
  const Route = "/api/rb/auth/verify-otp";
4
5
  const requestSchema = object({
@@ -54,24 +55,30 @@ const verifyOtp = async (payload, ctx) => {
54
55
  user.emailVerificationCode = void 0;
55
56
  user.emailVerificationExpiresAt = void 0;
56
57
  await user.save();
57
- const tenantId = user.tenants?.[0]?.toString?.() || "00000000";
58
58
  const signedInTenants = (user.tenants || []).map(String);
59
- const tenantRolesMap = user.get("tenantRoles");
60
- const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : void 0;
61
- if (!ctx.req.session) {
59
+ const defaultTenantId = signedInTenants[0];
60
+ if (!defaultTenantId) {
62
61
  ctx.res.status(500);
63
62
  return {
64
63
  success: false,
65
- error: "session_unavailable"
64
+ error: "tenant_unavailable"
66
65
  };
67
66
  }
68
- ctx.req.session.user = {
69
- id: user._id.toString(),
67
+ const tenantId = defaultTenantId;
68
+ const tenantRolesMap = user.get("tenantRoles");
69
+ const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : void 0;
70
+ if (!completeAuthSignIn(ctx, {
71
+ userId: user._id.toString(),
70
72
  currentTenantId: tenantId,
71
73
  signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],
72
- isEntryGateAuthorized: true,
73
74
  tenantRoles
74
- };
75
+ })) {
76
+ ctx.res.status(500);
77
+ return {
78
+ success: false,
79
+ error: "session_unavailable"
80
+ };
81
+ }
75
82
  return {
76
83
  success: true,
77
84
  userId: user._id.toString(),
@@ -84,4 +91,4 @@ const handler = (api) => {
84
91
  export {
85
92
  handler as default
86
93
  };
87
- //# sourceMappingURL=handler-Ck7oLQ_R.js.map
94
+ //# sourceMappingURL=handler-gfRB07A8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler-gfRB07A8.js","sources":["../src/api/verify-otp/index.ts","../src/api/verify-otp/handler.ts"],"sourcesContent":["import { z } from \"zod\"\n\n\nexport const Route = \"/api/rb/auth/verify-otp\"\n\nexport const requestSchema = z.object({\n email: z.string().email(),\n code: z.string().length(6, \"Code must be 6 digits\"),\n rememberMe: z.boolean().default(true),\n})\n\nexport type RequestPayload = z.infer<typeof requestSchema>\n\nexport const responseSchema = z.object({\n success: z.boolean(),\n error: z.string().optional(),\n userId: z.string().optional(),\n tenantId: z.string().optional(),\n})\n\nexport type ResponsePayload = z.infer<typeof responseSchema>\n","import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\n\nimport { completeAuthSignIn } from \"../../session\"\nimport type { AuthSessionUser } from \"../../types\"\n\nimport * as VerifyOtp from \"./index\"\n\n\nconst verifyOtp: ApiHandler<VerifyOtp.RequestPayload, VerifyOtp.ResponsePayload, AuthSessionUser> = async (\n payload,\n ctx: Ctx<AuthSessionUser>\n): Promise<VerifyOtp.ResponsePayload> => {\n const User = await models.getGlobal(\"RBUser\", ctx)\n\n const parsed = VerifyOtp.requestSchema.safeParse(payload)\n\n if (!parsed.success) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_payload\" }\n }\n\n const { email, code } = parsed.data\n\n const user = await User.findOne({ email }, { emailVerificationCode: 1, emailVerificationExpiresAt: 1, tenants: 1, tenantRoles: 1 })\n\n if (!user) {\n ctx.res.status(404)\n return { success: false, error: \"user_not_found\" }\n }\n\n const storedCode = user.emailVerificationCode\n const expiresAt = user.emailVerificationExpiresAt\n\n const isExpired = expiresAt instanceof Date && expiresAt.getTime() < Date.now()\n if (!storedCode || storedCode !== code || isExpired) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_code\" }\n }\n\n user.emailVerificationCode = undefined\n user.emailVerificationExpiresAt = undefined\n await user.save()\n\n const signedInTenants = (user.tenants || []).map(String)\n const defaultTenantId = signedInTenants[0]\n if (!defaultTenantId) {\n ctx.res.status(500)\n return { success: false, error: \"tenant_unavailable\" }\n }\n const tenantId = defaultTenantId\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!completeAuthSignIn(ctx, {\n userId: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n tenantRoles,\n })) {\n ctx.res.status(500)\n return { success: false, error: \"session_unavailable\" }\n }\n\n return { success: true, userId: user._id.toString(), tenantId }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.post(VerifyOtp.Route, verifyOtp)\n}\n"],"names":["Route","requestSchema","z","email","string","code","length","rememberMe","default","success","boolean","error","optional","userId","tenantId","verifyOtp","payload","ctx","User","models","getGlobal","parsed","VerifyOtp","safeParse","res","status","data","user","findOne","emailVerificationCode","emailVerificationExpiresAt","tenants","tenantRoles","storedCode","expiresAt","isExpired","Date","getTime","now","undefined","save","signedInTenants","map","String","defaultTenantId","tenantRolesMap","get","Object","fromEntries","entries","completeAuthSignIn","_id","toString","currentTenantId","api","post"],"mappings":";;;AAGO,MAAMA,QAAQ;AAEd,MAAMC,gBAAgBC,OAAS;AAAA,EACpCC,OAAOD,OAAEE,EAASD,MAAAA;AAAAA,EAClBE,MAAMH,OAAEE,EAASE,OAAO,GAAG,uBAAuB;AAAA,EAClDC,YAAYL,UAAYM,QAAQ,IAAI;AACtC,CAAC;AAI6BN,OAAS;AAAA,EACrCO,SAASP,QAAEQ;AAAAA,EACXC,OAAOT,OAAEE,EAASQ,SAAAA;AAAAA,EAClBC,QAAQX,OAAEE,EAASQ,SAAAA;AAAAA,EACnBE,UAAUZ,OAAEE,EAASQ,SAAAA;AACvB,CAAC;ACTD,MAAMG,YAA8F,OAClGC,SACAC,QACuC;AACvC,QAAMC,OAAO,MAAMC,OAAOC,UAAU,UAAUH,GAAG;AAEjD,QAAMI,SAASC,cAAwBC,UAAUP,OAAO;AAExD,MAAI,CAACK,OAAOZ,SAAS;AACnBQ,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAM;AAAA,IAAER;AAAAA,IAAOE;AAAAA,EAAAA,IAASgB,OAAOK;AAE/B,QAAMC,OAAO,MAAMT,KAAKU,QAAQ;AAAA,IAAEzB;AAAAA,EAAAA,GAAS;AAAA,IAAE0B,uBAAuB;AAAA,IAAGC,4BAA4B;AAAA,IAAGC,SAAS;AAAA,IAAGC,aAAa;AAAA,EAAA,CAAG;AAElI,MAAI,CAACL,MAAM;AACTV,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMsB,aAAaN,KAAKE;AACxB,QAAMK,YAAYP,KAAKG;AAEvB,QAAMK,YAAYD,qBAAqBE,QAAQF,UAAUG,QAAAA,IAAYD,KAAKE,IAAAA;AAC1E,MAAI,CAACL,cAAcA,eAAe5B,QAAQ8B,WAAW;AACnDlB,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEAgB,OAAKE,wBAAwBU;AAC7BZ,OAAKG,6BAA6BS;AAClC,QAAMZ,KAAKa,KAAAA;AAEX,QAAMC,mBAAmBd,KAAKI,WAAW,CAAA,GAAIW,IAAIC,MAAM;AACvD,QAAMC,kBAAkBH,gBAAgB,CAAC;AACzC,MAAI,CAACG,iBAAiB;AACpB3B,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AACA,QAAMG,WAAW8B;AACjB,QAAMC,iBAAiBlB,KAAKmB,IAAI,aAAa;AAC7C,QAAMd,cAAca,iBAAiBE,OAAOC,YAAYH,eAAeI,QAAAA,CAAS,IAAIV;AAEpF,MAAI,CAACW,mBAAmBjC,KAAK;AAAA,IAC3BJ,QAAQc,KAAKwB,IAAIC,SAAAA;AAAAA,IACjBC,iBAAiBvC;AAAAA,IACjB2B,iBAAiBA,gBAAgBnC,SAASmC,kBAAkB,CAAC3B,QAAQ;AAAA,IACrEkB;AAAAA,EAAAA,CACD,GAAG;AACFf,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,SAAO;AAAA,IAAEF,SAAS;AAAA,IAAMI,QAAQc,KAAKwB,IAAIC,SAAAA;AAAAA,IAAYtC;AAAAA,EAAAA;AACvD;AAEA,MAAA,UAAe,CAACwC,QAA8B;AAC5CA,MAAIC,KAAKjC,OAAiBP,SAAS;AACrC;"}
@@ -1,6 +1,7 @@
1
1
  import crypto from "crypto";
2
2
  import { models } from "@rpcbase/db";
3
3
  import { hashPasswordForStorage } from "@rpcbase/server";
4
+ import { c as completeAuthSignIn } from "../session-DoTNxRRA.js";
4
5
  const STORE_KEY = /* @__PURE__ */ Symbol.for("@rpcbase/auth/oauthProviders");
5
6
  const getStore = () => {
6
7
  const anyGlobal = globalThis;
@@ -619,17 +620,31 @@ const processOAuthCallback = async ({
619
620
  $set: setFields
620
621
  });
621
622
  }
622
- const tenantId = user.tenants?.[0]?.toString?.() || "00000000";
623
623
  const signedInTenants = (user.tenants || []).map(String);
624
+ const tenantId = signedInTenants[0];
625
+ if (!tenantId) {
626
+ return {
627
+ success: false,
628
+ type: "error",
629
+ error: "tenant_unavailable",
630
+ redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`
631
+ };
632
+ }
624
633
  const tenantRolesMap = user.get("tenantRoles");
625
634
  const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : void 0;
626
- ctx.req.session.user = {
627
- id: user._id.toString(),
635
+ if (!completeAuthSignIn(ctx, {
636
+ userId: user._id.toString(),
628
637
  currentTenantId: tenantId,
629
638
  signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],
630
- isEntryGateAuthorized: true,
631
639
  tenantRoles
632
- };
640
+ })) {
641
+ return {
642
+ success: false,
643
+ type: "error",
644
+ error: "session_unavailable",
645
+ redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable`
646
+ };
647
+ }
633
648
  try {
634
649
  if (OAuthRequestModel) {
635
650
  await OAuthRequestModel.deleteOne({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/oauth/config.ts","../../src/oauth/jwt.ts","../../src/oauth/oidc.ts","../../src/oauth/pkce.ts","../../src/oauth/providerId.ts","../../src/oauth/lib.ts"],"sourcesContent":["export type OAuthProviderConfig = {\n issuer: string\n clientId: string\n clientSecret?: string\n scope: string\n callbackPath: string\n}\n\ntype OAuthProvidersConfig = Record<string, OAuthProviderConfig>\n\ntype OAuthProvidersStore = {\n providers: OAuthProvidersConfig\n}\n\nconst STORE_KEY = Symbol.for(\"@rpcbase/auth/oauthProviders\")\n\nconst getStore = (): OAuthProvidersStore => {\n const anyGlobal = globalThis as unknown as Record<string | symbol, unknown>\n const existing = anyGlobal[STORE_KEY] as OAuthProvidersStore | undefined\n if (existing && typeof existing === \"object\" && existing.providers && typeof existing.providers === \"object\") {\n return existing\n }\n\n const created: OAuthProvidersStore = { providers: {} }\n anyGlobal[STORE_KEY] = created\n return created\n}\n\nconst normalizeProviders = (providers: Record<string, OAuthProviderConfig>): OAuthProvidersConfig => {\n const result: OAuthProvidersConfig = {}\n\n const isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n }\n\n for (const [providerIdRaw, value] of Object.entries(providers)) {\n const providerId = providerIdRaw.trim()\n if (!providerId) continue\n\n const issuer = typeof value?.issuer === \"string\" ? value.issuer.trim() : \"\"\n const clientId = typeof value?.clientId === \"string\" ? value.clientId.trim() : \"\"\n if (!issuer) throw new Error(`oauth provider \"${providerId}\" missing issuer`)\n if (!clientId) throw new Error(`oauth provider \"${providerId}\" missing clientId`)\n\n const clientSecret = typeof value?.clientSecret === \"string\" && value.clientSecret.trim()\n ? value.clientSecret\n : undefined\n\n const scope = typeof value?.scope === \"string\" ? value.scope.trim() : \"\"\n if (!scope) throw new Error(`oauth provider \"${providerId}\" missing scope`)\n\n const callbackPath = typeof value?.callbackPath === \"string\"\n ? value.callbackPath.trim()\n : \"\"\n if (!callbackPath) throw new Error(`oauth provider \"${providerId}\" missing callbackPath`)\n if (!isSafeRedirectPath(callbackPath)) throw new Error(`oauth provider \"${providerId}\" has invalid callbackPath`)\n\n result[providerId] = {\n issuer,\n clientId,\n clientSecret,\n scope,\n callbackPath,\n }\n }\n\n return result\n}\n\nexport const configureOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n const normalized = normalizeProviders(providers)\n store.providers = { ...store.providers, ...normalized }\n}\n\nexport const setOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n store.providers = normalizeProviders(providers)\n}\n\nexport const getOAuthProviderConfig = (providerId: string): OAuthProviderConfig | null => {\n const store = getStore()\n return store.providers[providerId] ?? null\n}\n","const decodeBase64Url = (value: string) => {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((value.length + 3) % 4)\n return Buffer.from(padded, \"base64\").toString(\"utf8\")\n}\n\nexport const decodeJwtPayload = <T = Record<string, unknown>>(token: string): T | null => {\n const parts = token.split(\".\")\n if (parts.length < 2) return null\n\n try {\n const json = decodeBase64Url(parts[1])\n const parsed = JSON.parse(json) as T\n if (!parsed || typeof parsed !== \"object\") return null\n return parsed\n } catch {\n return null\n }\n}\n\n","export type OidcWellKnown = {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint?: string\n jwks_uri?: string\n}\n\nconst cache = new Map<string, Promise<OidcWellKnown>>()\n\nconst normalizeIssuer = (raw: string) => raw.trim().replace(/\\/+$/, \"\")\n\nexport const getOidcWellKnown = async (issuerRaw: string): Promise<OidcWellKnown> => {\n const issuer = normalizeIssuer(issuerRaw)\n if (!issuer) {\n throw new Error(\"OIDC issuer is required\")\n }\n\n const existing = cache.get(issuer)\n if (existing) {\n return existing\n }\n\n const loader = (async () => {\n const url = new URL(\"/.well-known/openid-configuration\", issuer)\n const response = await fetch(url, { headers: { Accept: \"application/json\" } })\n if (!response.ok) {\n const body = await response.text().catch(() => \"\")\n throw new Error(`Failed to fetch OIDC discovery document: ${response.status} ${body}`)\n }\n\n const json = await response.json().catch(() => null) as Partial<OidcWellKnown> | null\n if (!json || typeof json !== \"object\") {\n throw new Error(\"Invalid OIDC discovery document\")\n }\n\n const authorizationEndpoint = typeof json.authorization_endpoint === \"string\"\n ? json.authorization_endpoint\n : \"\"\n const tokenEndpoint = typeof json.token_endpoint === \"string\"\n ? json.token_endpoint\n : \"\"\n const issuerValue = typeof json.issuer === \"string\" ? json.issuer : issuer\n const userinfoEndpoint = typeof json.userinfo_endpoint === \"string\" ? json.userinfo_endpoint : undefined\n const jwksUri = typeof json.jwks_uri === \"string\" ? json.jwks_uri : undefined\n\n if (!authorizationEndpoint || !tokenEndpoint) {\n throw new Error(\"OIDC discovery document missing required endpoints\")\n }\n\n return {\n issuer: issuerValue,\n authorization_endpoint: authorizationEndpoint,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: userinfoEndpoint,\n jwks_uri: jwksUri,\n } satisfies OidcWellKnown\n })()\n\n cache.set(issuer, loader)\n\n try {\n return await loader\n } catch (err) {\n cache.delete(issuer)\n throw err\n }\n}\n\n","import crypto from \"crypto\"\n\n\nexport const base64UrlEncode = (input: Buffer) => input\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const generatePkcePair = () => {\n const verifier = base64UrlEncode(crypto.randomBytes(32))\n const challenge = base64UrlEncode(crypto.createHash(\"sha256\").update(verifier).digest())\n\n return { verifier, challenge }\n}\n\n","const RESERVED_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nexport const isSafeOAuthProviderId = (value: string) => {\n const providerId = value.trim()\n if (!providerId) return false\n if (providerId.length > 128) return false\n if (RESERVED_KEYS.has(providerId)) return false\n return /^[a-zA-Z0-9_-]+$/.test(providerId)\n}\n\n","import crypto from \"crypto\"\n\nimport { ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\nimport { hashPasswordForStorage } from \"@rpcbase/server\"\n\nimport type { AuthSessionUser } from \"../types\"\nimport { getOAuthProviderConfig } from \"./config\"\nimport { decodeJwtPayload } from \"./jwt\"\nimport { getOidcWellKnown } from \"./oidc\"\nimport { generatePkcePair } from \"./pkce\"\nimport { isSafeOAuthProviderId } from \"./providerId\"\n\n\nconst OAUTH_REQUEST_TTL_MS = 10 * 60 * 1000\nconst OAUTH_STATE_COOKIE_NAME = \"rb_oauth_state\"\ntype OAuthCtx = Ctx<AuthSessionUser>\ntype OAuthRequestRecord = {\n returnTo?: unknown\n codeVerifier?: unknown\n}\n\nconst getQueryString = (value: unknown) => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0]\n return null\n}\n\nconst getCookieValue = (ctx: OAuthCtx, name: string): string | null => {\n const header = ctx.req.headers?.cookie\n if (typeof header !== \"string\" || !header) return null\n\n for (const part of header.split(\";\")) {\n const [rawKey, ...rest] = part.split(\"=\")\n const key = rawKey?.trim()\n if (!key || key !== name) continue\n const rawValue = rest.join(\"=\").trim()\n if (!rawValue) return \"\"\n try {\n return decodeURIComponent(rawValue)\n } catch {\n return rawValue\n }\n }\n\n return null\n}\n\nconst isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n}\n\nconst getRequestOrigin = (ctx: OAuthCtx) => {\n const protoHeader = ctx.req.headers[\"x-forwarded-proto\"]\n const hostHeader = ctx.req.headers[\"x-forwarded-host\"]\n\n const protocol = typeof protoHeader === \"string\"\n ? protoHeader.split(\",\")[0].trim()\n : ctx.req.protocol\n\n const host = typeof hostHeader === \"string\"\n ? hostHeader.split(\",\")[0].trim()\n : ctx.req.get(\"host\")\n\n return protocol && host ? `${protocol}://${host}` : \"\"\n}\n\nconst resolveCallbackPath = (callbackPath: string) => {\n const trimmed = callbackPath.trim()\n return trimmed && isSafeRedirectPath(trimmed) ? trimmed : null\n}\n\nconst readTextBody = async (req: Pick<OAuthCtx[\"req\"], \"on\" | \"setEncoding\">) =>\n await new Promise<string>((resolve, reject) => {\n let body = \"\"\n if (typeof req.setEncoding === \"function\") {\n req.setEncoding(\"utf8\")\n }\n\n req.on(\"data\", (chunk) => {\n body += String(chunk)\n if (body.length > 32_768) {\n reject(new Error(\"request_body_too_large\"))\n }\n })\n req.on(\"end\", () => resolve(body))\n req.on(\"error\", reject)\n })\n\nconst getFormPostParams = async (ctx: OAuthCtx): Promise<Record<string, string> | null> => {\n if (ctx.req.method !== \"POST\") return null\n\n const contentType = typeof ctx.req.headers[\"content-type\"] === \"string\" ? ctx.req.headers[\"content-type\"] : \"\"\n if (!contentType.includes(\"application/x-www-form-urlencoded\")) return null\n\n const body = await readTextBody(ctx.req)\n const params = new URLSearchParams(body)\n\n const result: Record<string, string> = {}\n for (const [key, value] of params.entries()) {\n result[key] = value\n }\n\n return result\n}\n\nconst resolveProviderId = (ctx: OAuthCtx, providerIdOverride?: string) =>\n (providerIdOverride ?? String(ctx.req.params?.provider ?? \"\")).trim()\n\nconst RESERVED_AUTH_PARAM_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nconst normalizeAuthorizationParams = (value: unknown): Record<string, string> | undefined => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined\n\n const result: Record<string, string> = {}\n for (const [keyRaw, valueRaw] of Object.entries(value)) {\n const key = keyRaw.trim()\n if (!key) continue\n if (RESERVED_AUTH_PARAM_KEYS.has(key)) continue\n const val = typeof valueRaw === \"string\" ? valueRaw.trim() : \"\"\n if (!val) continue\n result[key] = val\n }\n\n return Object.keys(result).length ? result : undefined\n}\n\nexport type OAuthStartResult =\n | { success: true; redirectUrl: string }\n | { success: false; error: string; statusCode: number }\n\nexport const getOAuthStartRedirectUrl = async ({\n ctx,\n providerId: providerIdOverride,\n returnTo,\n authorizationParams,\n}: {\n ctx: OAuthCtx\n providerId?: string\n returnTo?: string | null\n authorizationParams?: Record<string, string>\n}): Promise<OAuthStartResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, error: \"missing_provider\", statusCode: 400 }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, error: \"invalid_provider\", statusCode: 400 }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, error: \"unknown_provider\", statusCode: 404 }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, error: \"origin_unavailable\", statusCode: 500 }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, error: \"invalid_callback_path\", statusCode: 500 }\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\")\n const { verifier, challenge } = generatePkcePair()\n\n const safeReturnTo = typeof returnTo === \"string\" && isSafeRedirectPath(returnTo) ? returnTo : undefined\n\n try {\n const OAuthRequest = await models.getGlobal(\"RBOAuthRequest\", ctx)\n const now = new Date()\n await OAuthRequest.create({\n _id: state,\n providerId,\n codeVerifier: verifier,\n returnTo: safeReturnTo,\n createdAt: now,\n expiresAt: new Date(now.getTime() + OAUTH_REQUEST_TTL_MS),\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_store_request\", err)\n return { success: false, error: \"oauth_request_store_failed\", statusCode: 500 }\n }\n\n try {\n ctx.res.cookie(OAUTH_STATE_COOKIE_NAME, `${providerId}:${state}`, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n maxAge: OAUTH_REQUEST_TTL_MS,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_set_state_cookie\", err)\n return { success: false, error: \"oauth_cookie_set_failed\", statusCode: 500 }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const url = new URL(oidc.authorization_endpoint)\n url.searchParams.set(\"client_id\", provider.clientId)\n url.searchParams.set(\"redirect_uri\", redirectUri)\n url.searchParams.set(\"response_type\", \"code\")\n url.searchParams.set(\"scope\", provider.scope)\n url.searchParams.set(\"state\", state)\n url.searchParams.set(\"code_challenge\", challenge)\n url.searchParams.set(\"code_challenge_method\", \"S256\")\n const extraAuthorizationParams = normalizeAuthorizationParams(authorizationParams)\n for (const [key, value] of Object.entries(extraAuthorizationParams ?? {})) {\n if (url.searchParams.has(key)) continue\n url.searchParams.set(key, value)\n }\n\n return { success: true, redirectUrl: url.toString() }\n}\n\nexport type OAuthCallbackResult =\n | {\n success: true\n type: \"signed_in\"\n redirectPath: string\n userId: string\n tenantId: string\n signedInTenants: string[]\n }\n | {\n success: false\n type: \"missing_user\"\n providerId: string\n subject: string\n email?: string\n name?: string\n redirectPath?: string\n }\n | {\n success: false\n type: \"error\"\n error: string\n redirectPath: string\n }\n\nconst OAUTH_SUCCESS_REDIRECT_PATH = \"/onboarding\"\nconst AUTH_ERROR_REDIRECT_BASE = \"/auth/sign-in\"\n\nexport const processOAuthCallback = async ({\n ctx,\n providerId: providerIdOverride,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n ctx: OAuthCtx\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n}): Promise<OAuthCallbackResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, type: \"error\", error: \"missing_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_provider` }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, type: \"error\", error: \"invalid_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_provider` }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, type: \"error\", error: \"unknown_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, type: \"error\", error: \"origin_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, type: \"error\", error: \"invalid_callback_path\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` }\n }\n\n const bodyParams = await getFormPostParams(ctx)\n\n const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? \"\"\n const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? \"\"\n const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? \"\"\n\n if (!code || !state) {\n return { success: false, type: \"error\", error: \"missing_code_or_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` }\n }\n\n const stateCookieValue = getCookieValue(ctx, OAUTH_STATE_COOKIE_NAME)\n if (stateCookieValue !== `${providerId}:${state}`) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n let oauthRequest: OAuthRequestRecord | null = null\n let OAuthRequestModel: Awaited<ReturnType<typeof models.getGlobal>> | null = null\n try {\n OAuthRequestModel = await models.getGlobal(\"RBOAuthRequest\", ctx)\n oauthRequest = await OAuthRequestModel.findOne({ _id: state, providerId }).lean() as OAuthRequestRecord | null\n } catch (err) {\n console.warn(\"oauth::failed_to_load_request\", err)\n return { success: false, type: \"error\", error: \"oauth_request_load_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=oauth_request_load_failed` }\n }\n\n if (!oauthRequest) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n const returnTo = typeof oauthRequest.returnTo === \"string\" ? oauthRequest.returnTo : undefined\n const codeVerifier = typeof oauthRequest.codeVerifier === \"string\" ? oauthRequest.codeVerifier : \"\"\n if (!codeVerifier) {\n return { success: false, type: \"error\", error: \"missing_code_verifier\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const tokenBody = new URLSearchParams()\n tokenBody.set(\"grant_type\", \"authorization_code\")\n tokenBody.set(\"code\", code)\n tokenBody.set(\"redirect_uri\", redirectUri)\n tokenBody.set(\"client_id\", provider.clientId)\n tokenBody.set(\"code_verifier\", codeVerifier)\n if (provider.clientSecret) {\n tokenBody.set(\"client_secret\", provider.clientSecret)\n }\n\n const tokenResponse = await fetch(oidc.token_endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: tokenBody.toString(),\n })\n\n const tokenJson = await tokenResponse.json().catch(() => null) as Record<string, unknown> | null\n\n if (!tokenResponse.ok || !tokenJson || typeof tokenJson !== \"object\") {\n const body = tokenJson ? JSON.stringify(tokenJson) : \"\"\n console.warn(\"oauth::token_exchange failed\", tokenResponse.status, body)\n return { success: false, type: \"error\", error: \"token_exchange_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=token_exchange_failed` }\n }\n\n const accessToken = typeof tokenJson.access_token === \"string\" ? tokenJson.access_token : \"\"\n const refreshToken = typeof tokenJson.refresh_token === \"string\" ? tokenJson.refresh_token : undefined\n const idToken = typeof tokenJson.id_token === \"string\" ? tokenJson.id_token : undefined\n const scope = typeof tokenJson.scope === \"string\" ? tokenJson.scope : undefined\n const tokenType = typeof tokenJson.token_type === \"string\" ? tokenJson.token_type : undefined\n const expiresIn = typeof tokenJson.expires_in === \"number\"\n ? tokenJson.expires_in\n : typeof tokenJson.expires_in === \"string\"\n ? Number(tokenJson.expires_in)\n : undefined\n const expiresInSeconds = typeof expiresIn === \"number\" && Number.isFinite(expiresIn) ? expiresIn : null\n const expiresAt = expiresInSeconds !== null ? new Date(Date.now() + expiresInSeconds * 1000) : undefined\n\n let userInfo: Record<string, unknown> | null = null\n\n if (oidc.userinfo_endpoint && accessToken) {\n const userInfoResponse = await fetch(oidc.userinfo_endpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n })\n\n if (userInfoResponse.ok) {\n userInfo = await userInfoResponse.json().catch(() => null) as Record<string, unknown> | null\n }\n }\n\n const idTokenPayload = idToken ? decodeJwtPayload<Record<string, unknown>>(idToken) : null\n const accessTokenPayload = decodeJwtPayload<Record<string, unknown>>(accessToken)\n\n const subject = typeof userInfo?.sub === \"string\"\n ? userInfo.sub\n : typeof idTokenPayload?.sub === \"string\"\n ? idTokenPayload.sub\n : typeof accessTokenPayload?.sub === \"string\"\n ? accessTokenPayload.sub\n : \"\"\n\n if (!subject) {\n return { success: false, type: \"error\", error: \"missing_subject\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_subject` }\n }\n\n const email = typeof userInfo?.email === \"string\"\n ? userInfo.email\n : typeof idTokenPayload?.email === \"string\"\n ? idTokenPayload.email\n : undefined\n\n const name = typeof userInfo?.name === \"string\"\n ? userInfo.name\n : typeof idTokenPayload?.name === \"string\"\n ? idTokenPayload.name\n : undefined\n\n let oauthUser: unknown = null\n if (oauthUserRaw) {\n try {\n oauthUser = JSON.parse(oauthUserRaw) as unknown\n } catch {\n oauthUser = null\n }\n }\n const oauthUserRecord = oauthUser && typeof oauthUser === \"object\"\n ? (oauthUser as Record<string, unknown>)\n : null\n const oauthUserEmail = typeof oauthUserRecord?.email === \"string\" ? oauthUserRecord.email.trim() : \"\"\n const oauthUserNameRecord = oauthUserRecord?.name && typeof oauthUserRecord.name === \"object\"\n ? (oauthUserRecord.name as Record<string, unknown>)\n : null\n const oauthUserNameFirst = typeof oauthUserNameRecord?.firstName === \"string\" ? oauthUserNameRecord.firstName.trim() : \"\"\n const oauthUserNameLast = typeof oauthUserNameRecord?.lastName === \"string\" ? oauthUserNameRecord.lastName.trim() : \"\"\n const oauthUserName = [oauthUserNameFirst, oauthUserNameLast].filter(Boolean).join(\" \").trim()\n\n const resolvedEmail = email ?? (oauthUserEmail || undefined)\n const resolvedName = name ?? (oauthUserName || undefined)\n\n const [User, Tenant] = await Promise.all([\n models.getGlobal(\"RBUser\", ctx),\n models.getGlobal(\"RBTenant\", ctx),\n ])\n\n const subjectQueryKey = `oauthProviders.${providerId}.subject`\n let user = await User.findOne({ [subjectQueryKey]: subject })\n\n if (!user && resolvedEmail) {\n user = await User.findOne({ email: resolvedEmail })\n }\n\n const shouldCreateUser = createUserOnFirstSignIn ?? true\n if (!user && !shouldCreateUser) {\n const redirectPath = missingUserRedirectPath\n\n const result: OAuthCallbackResult = {\n success: false,\n type: \"missing_user\",\n providerId,\n subject,\n email: resolvedEmail,\n name: resolvedName,\n }\n\n if (redirectPath && isSafeRedirectPath(redirectPath)) {\n const url = new URL(redirectPath, origin)\n url.searchParams.set(\"oauth_provider\", providerId)\n if (resolvedEmail) url.searchParams.set(\"email\", resolvedEmail)\n if (resolvedName) url.searchParams.set(\"name\", resolvedName)\n result.redirectPath = `${url.pathname}${url.search}`\n }\n\n return result\n }\n\n if (!ctx.req.session) {\n return { success: false, type: \"error\", error: \"session_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` }\n }\n\n const now = new Date()\n\n let providerCreatedAt: Date | undefined\n const oauthProviders = user?.get(\"oauthProviders\") as Map<string, { createdAt?: unknown }> | undefined\n const existingProvider = oauthProviders?.get(providerId)\n if (existingProvider?.createdAt instanceof Date) {\n providerCreatedAt = existingProvider.createdAt\n }\n\n const oauthProviderPayload = {\n subject,\n email: resolvedEmail,\n name: resolvedName,\n accessToken,\n refreshToken,\n idToken,\n scope,\n tokenType,\n expiresAt,\n rawUserInfo: userInfo ?? undefined,\n createdAt: providerCreatedAt ?? now,\n updatedAt: now,\n }\n\n if (!user) {\n const tenantId = crypto.randomUUID()\n const password = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n\n user = new User({\n email: resolvedEmail,\n name: resolvedName,\n password,\n tenants: [tenantId],\n tenantRoles: {\n [tenantId]: [\"owner\"],\n },\n oauthProviders: {\n [providerId]: oauthProviderPayload,\n },\n })\n\n await user.save()\n\n try {\n await Tenant.create({\n tenantId,\n name: resolvedEmail || subject,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_create_tenant\", err)\n }\n } else {\n const setFields: Record<string, unknown> = {\n [`oauthProviders.${providerId}`]: oauthProviderPayload,\n }\n\n if (!user.email && resolvedEmail) {\n setFields.email = resolvedEmail\n }\n\n if (!user.name && resolvedName) {\n setFields.name = resolvedName\n }\n\n await User.updateOne({ _id: user._id }, { $set: setFields })\n }\n\n const tenantId = user.tenants?.[0]?.toString?.() || \"00000000\"\n const signedInTenants = (user.tenants || []).map(String)\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n ctx.req.session.user = {\n id: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n isEntryGateAuthorized: true,\n tenantRoles,\n }\n\n try {\n if (OAuthRequestModel) {\n await OAuthRequestModel.deleteOne({ _id: state, providerId })\n }\n } catch (err) {\n console.warn(\"oauth::failed_to_delete_request\", err)\n }\n\n try {\n ctx.res.clearCookie(OAUTH_STATE_COOKIE_NAME, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_clear_state_cookie\", err)\n }\n\n const redirectPath = returnTo && isSafeRedirectPath(returnTo)\n ? returnTo\n : successRedirectPath && isSafeRedirectPath(successRedirectPath)\n ? successRedirectPath\n : OAUTH_SUCCESS_REDIRECT_PATH\n\n return {\n success: true,\n type: \"signed_in\",\n redirectPath,\n userId: user._id.toString(),\n tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n }\n}\n\nexport const createOAuthStartHandler = ({\n providerId,\n getAuthorizationParams,\n}: {\n providerId?: string\n getAuthorizationParams?: (providerId: string) => Record<string, string> | undefined\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const resolvedProviderId = resolveProviderId(ctx, providerId)\n const providerAuthorizationParams = resolvedProviderId && getAuthorizationParams\n ? getAuthorizationParams(resolvedProviderId)\n : undefined\n const returnTo = getQueryString(ctx.req.query?.returnTo)?.trim()\n const result = await getOAuthStartRedirectUrl({\n ctx,\n providerId: resolvedProviderId,\n returnTo,\n authorizationParams: providerAuthorizationParams,\n })\n\n if (!result.success) {\n ctx.res.status(result.statusCode)\n return { success: false, error: result.error }\n }\n\n ctx.res.redirect(result.redirectUrl)\n return { success: true }\n}\n\nexport const createOAuthCallbackHandler = ({\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const result = await processOAuthCallback({\n ctx,\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n })\n\n if (result.type === \"error\") {\n ctx.res.redirect(result.redirectPath)\n return { success: false, error: result.error }\n }\n\n if (result.type === \"missing_user\") {\n if (result.redirectPath) {\n ctx.res.redirect(result.redirectPath)\n } else {\n ctx.res.redirect(\"/auth/sign-up\")\n }\n return { success: false, error: \"user_not_found\" }\n }\n\n ctx.res.redirect(result.redirectPath)\n return { success: true }\n}\n\nconst base64UrlEncode = (input: Buffer | string) =>\n Buffer.from(input)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const createAppleClientSecret = ({\n teamId,\n clientId,\n keyId,\n privateKeyPem,\n now = new Date(),\n expiresInSeconds = 10 * 60,\n}: {\n teamId: string\n clientId: string\n keyId: string\n privateKeyPem: string\n now?: Date\n expiresInSeconds?: number\n}) => {\n const teamIdValue = teamId.trim()\n const clientIdValue = clientId.trim()\n const keyIdValue = keyId.trim()\n const privateKeyPemValue = privateKeyPem.trim()\n\n if (!teamIdValue) throw new Error(\"teamId is required\")\n if (!clientIdValue) throw new Error(\"clientId is required\")\n if (!keyIdValue) throw new Error(\"keyId is required\")\n if (!privateKeyPemValue) throw new Error(\"privateKeyPem is required\")\n\n const nowSeconds = Math.floor(now.getTime() / 1000)\n const expiresIn = Number.isFinite(expiresInSeconds) ? expiresInSeconds : 10 * 60\n const exp = nowSeconds + Math.max(60, Math.min(expiresIn, 60 * 60 * 24 * 180))\n\n const header = { alg: \"ES256\", kid: keyIdValue, typ: \"JWT\" }\n const payload = {\n iss: teamIdValue,\n iat: nowSeconds,\n exp,\n aud: \"https://appleid.apple.com\",\n sub: clientIdValue,\n }\n\n const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`\n const signature = crypto.sign(\"sha256\", Buffer.from(signingInput), {\n key: privateKeyPemValue,\n dsaEncoding: \"ieee-p1363\",\n })\n\n return `${signingInput}.${base64UrlEncode(signature)}`\n}\n"],"names":["STORE_KEY","Symbol","for","getStore","anyGlobal","globalThis","existing","providers","created","normalizeProviders","result","isSafeRedirectPath","candidate","startsWith","providerIdRaw","value","Object","entries","providerId","trim","issuer","clientId","Error","clientSecret","undefined","scope","callbackPath","configureOAuthProviders","store","normalized","setOAuthProviders","getOAuthProviderConfig","decodeBase64Url","padded","replace","slice","length","Buffer","from","toString","decodeJwtPayload","token","parts","split","json","parsed","JSON","parse","cache","Map","normalizeIssuer","raw","getOidcWellKnown","issuerRaw","get","loader","url","URL","response","fetch","headers","Accept","ok","body","text","catch","status","authorizationEndpoint","authorization_endpoint","tokenEndpoint","token_endpoint","issuerValue","userinfoEndpoint","userinfo_endpoint","jwksUri","jwks_uri","set","err","delete","base64UrlEncode","input","generatePkcePair","verifier","crypto","randomBytes","challenge","createHash","update","digest","RESERVED_KEYS","Set","isSafeOAuthProviderId","has","test","OAUTH_REQUEST_TTL_MS","OAUTH_STATE_COOKIE_NAME","getQueryString","Array","isArray","getCookieValue","ctx","name","header","req","cookie","part","rawKey","rest","key","rawValue","join","decodeURIComponent","getRequestOrigin","protoHeader","hostHeader","protocol","host","resolveCallbackPath","trimmed","readTextBody","Promise","resolve","reject","setEncoding","on","chunk","String","getFormPostParams","method","contentType","includes","params","URLSearchParams","resolveProviderId","providerIdOverride","provider","RESERVED_AUTH_PARAM_KEYS","normalizeAuthorizationParams","keyRaw","valueRaw","val","keys","getOAuthStartRedirectUrl","returnTo","authorizationParams","success","error","statusCode","origin","isHttps","state","safeReturnTo","OAuthRequest","models","getGlobal","now","Date","create","_id","codeVerifier","createdAt","expiresAt","getTime","console","warn","res","httpOnly","secure","sameSite","path","maxAge","oidc","redirectUri","searchParams","extraAuthorizationParams","redirectUrl","OAUTH_SUCCESS_REDIRECT_PATH","AUTH_ERROR_REDIRECT_BASE","processOAuthCallback","createUserOnFirstSignIn","missingUserRedirectPath","successRedirectPath","type","redirectPath","bodyParams","code","query","oauthUserRaw","user","stateCookieValue","oauthRequest","OAuthRequestModel","findOne","lean","tokenBody","tokenResponse","tokenJson","stringify","accessToken","access_token","refreshToken","refresh_token","idToken","id_token","tokenType","token_type","expiresIn","expires_in","Number","expiresInSeconds","isFinite","userInfo","userInfoResponse","Authorization","idTokenPayload","accessTokenPayload","subject","sub","email","oauthUser","oauthUserRecord","oauthUserEmail","oauthUserNameRecord","oauthUserNameFirst","firstName","oauthUserNameLast","lastName","oauthUserName","filter","Boolean","resolvedEmail","resolvedName","User","Tenant","all","subjectQueryKey","shouldCreateUser","pathname","search","session","providerCreatedAt","oauthProviders","existingProvider","oauthProviderPayload","rawUserInfo","updatedAt","tenantId","randomUUID","password","hashPasswordForStorage","tenants","tenantRoles","save","setFields","updateOne","$set","signedInTenants","map","tenantRolesMap","fromEntries","id","currentTenantId","isEntryGateAuthorized","deleteOne","clearCookie","userId","createOAuthStartHandler","getAuthorizationParams","_payload","resolvedProviderId","providerAuthorizationParams","redirect","createOAuthCallbackHandler","createAppleClientSecret","teamId","keyId","privateKeyPem","teamIdValue","clientIdValue","keyIdValue","privateKeyPemValue","nowSeconds","Math","floor","exp","max","min","alg","kid","typ","payload","iss","iat","aud","signingInput","signature","sign","dsaEncoding"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/oauth/config.ts","../../src/oauth/jwt.ts","../../src/oauth/oidc.ts","../../src/oauth/pkce.ts","../../src/oauth/providerId.ts","../../src/oauth/lib.ts"],"sourcesContent":["export type OAuthProviderConfig = {\n issuer: string\n clientId: string\n clientSecret?: string\n scope: string\n callbackPath: string\n}\n\ntype OAuthProvidersConfig = Record<string, OAuthProviderConfig>\n\ntype OAuthProvidersStore = {\n providers: OAuthProvidersConfig\n}\n\nconst STORE_KEY = Symbol.for(\"@rpcbase/auth/oauthProviders\")\n\nconst getStore = (): OAuthProvidersStore => {\n const anyGlobal = globalThis as unknown as Record<string | symbol, unknown>\n const existing = anyGlobal[STORE_KEY] as OAuthProvidersStore | undefined\n if (existing && typeof existing === \"object\" && existing.providers && typeof existing.providers === \"object\") {\n return existing\n }\n\n const created: OAuthProvidersStore = { providers: {} }\n anyGlobal[STORE_KEY] = created\n return created\n}\n\nconst normalizeProviders = (providers: Record<string, OAuthProviderConfig>): OAuthProvidersConfig => {\n const result: OAuthProvidersConfig = {}\n\n const isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n }\n\n for (const [providerIdRaw, value] of Object.entries(providers)) {\n const providerId = providerIdRaw.trim()\n if (!providerId) continue\n\n const issuer = typeof value?.issuer === \"string\" ? value.issuer.trim() : \"\"\n const clientId = typeof value?.clientId === \"string\" ? value.clientId.trim() : \"\"\n if (!issuer) throw new Error(`oauth provider \"${providerId}\" missing issuer`)\n if (!clientId) throw new Error(`oauth provider \"${providerId}\" missing clientId`)\n\n const clientSecret = typeof value?.clientSecret === \"string\" && value.clientSecret.trim()\n ? value.clientSecret\n : undefined\n\n const scope = typeof value?.scope === \"string\" ? value.scope.trim() : \"\"\n if (!scope) throw new Error(`oauth provider \"${providerId}\" missing scope`)\n\n const callbackPath = typeof value?.callbackPath === \"string\"\n ? value.callbackPath.trim()\n : \"\"\n if (!callbackPath) throw new Error(`oauth provider \"${providerId}\" missing callbackPath`)\n if (!isSafeRedirectPath(callbackPath)) throw new Error(`oauth provider \"${providerId}\" has invalid callbackPath`)\n\n result[providerId] = {\n issuer,\n clientId,\n clientSecret,\n scope,\n callbackPath,\n }\n }\n\n return result\n}\n\nexport const configureOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n const normalized = normalizeProviders(providers)\n store.providers = { ...store.providers, ...normalized }\n}\n\nexport const setOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n store.providers = normalizeProviders(providers)\n}\n\nexport const getOAuthProviderConfig = (providerId: string): OAuthProviderConfig | null => {\n const store = getStore()\n return store.providers[providerId] ?? null\n}\n","const decodeBase64Url = (value: string) => {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((value.length + 3) % 4)\n return Buffer.from(padded, \"base64\").toString(\"utf8\")\n}\n\nexport const decodeJwtPayload = <T = Record<string, unknown>>(token: string): T | null => {\n const parts = token.split(\".\")\n if (parts.length < 2) return null\n\n try {\n const json = decodeBase64Url(parts[1])\n const parsed = JSON.parse(json) as T\n if (!parsed || typeof parsed !== \"object\") return null\n return parsed\n } catch {\n return null\n }\n}\n\n","export type OidcWellKnown = {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint?: string\n jwks_uri?: string\n}\n\nconst cache = new Map<string, Promise<OidcWellKnown>>()\n\nconst normalizeIssuer = (raw: string) => raw.trim().replace(/\\/+$/, \"\")\n\nexport const getOidcWellKnown = async (issuerRaw: string): Promise<OidcWellKnown> => {\n const issuer = normalizeIssuer(issuerRaw)\n if (!issuer) {\n throw new Error(\"OIDC issuer is required\")\n }\n\n const existing = cache.get(issuer)\n if (existing) {\n return existing\n }\n\n const loader = (async () => {\n const url = new URL(\"/.well-known/openid-configuration\", issuer)\n const response = await fetch(url, { headers: { Accept: \"application/json\" } })\n if (!response.ok) {\n const body = await response.text().catch(() => \"\")\n throw new Error(`Failed to fetch OIDC discovery document: ${response.status} ${body}`)\n }\n\n const json = await response.json().catch(() => null) as Partial<OidcWellKnown> | null\n if (!json || typeof json !== \"object\") {\n throw new Error(\"Invalid OIDC discovery document\")\n }\n\n const authorizationEndpoint = typeof json.authorization_endpoint === \"string\"\n ? json.authorization_endpoint\n : \"\"\n const tokenEndpoint = typeof json.token_endpoint === \"string\"\n ? json.token_endpoint\n : \"\"\n const issuerValue = typeof json.issuer === \"string\" ? json.issuer : issuer\n const userinfoEndpoint = typeof json.userinfo_endpoint === \"string\" ? json.userinfo_endpoint : undefined\n const jwksUri = typeof json.jwks_uri === \"string\" ? json.jwks_uri : undefined\n\n if (!authorizationEndpoint || !tokenEndpoint) {\n throw new Error(\"OIDC discovery document missing required endpoints\")\n }\n\n return {\n issuer: issuerValue,\n authorization_endpoint: authorizationEndpoint,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: userinfoEndpoint,\n jwks_uri: jwksUri,\n } satisfies OidcWellKnown\n })()\n\n cache.set(issuer, loader)\n\n try {\n return await loader\n } catch (err) {\n cache.delete(issuer)\n throw err\n }\n}\n\n","import crypto from \"crypto\"\n\n\nexport const base64UrlEncode = (input: Buffer) => input\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const generatePkcePair = () => {\n const verifier = base64UrlEncode(crypto.randomBytes(32))\n const challenge = base64UrlEncode(crypto.createHash(\"sha256\").update(verifier).digest())\n\n return { verifier, challenge }\n}\n\n","const RESERVED_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nexport const isSafeOAuthProviderId = (value: string) => {\n const providerId = value.trim()\n if (!providerId) return false\n if (providerId.length > 128) return false\n if (RESERVED_KEYS.has(providerId)) return false\n return /^[a-zA-Z0-9_-]+$/.test(providerId)\n}\n\n","import crypto from \"crypto\"\n\nimport { ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\nimport { hashPasswordForStorage } from \"@rpcbase/server\"\n\nimport { completeAuthSignIn } from \"../session\"\nimport type { AuthSessionUser } from \"../types\"\nimport { getOAuthProviderConfig } from \"./config\"\nimport { decodeJwtPayload } from \"./jwt\"\nimport { getOidcWellKnown } from \"./oidc\"\nimport { generatePkcePair } from \"./pkce\"\nimport { isSafeOAuthProviderId } from \"./providerId\"\n\n\nconst OAUTH_REQUEST_TTL_MS = 10 * 60 * 1000\nconst OAUTH_STATE_COOKIE_NAME = \"rb_oauth_state\"\ntype OAuthCtx = Ctx<AuthSessionUser>\ntype OAuthRequestRecord = {\n returnTo?: unknown\n codeVerifier?: unknown\n}\n\nconst getQueryString = (value: unknown) => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0]\n return null\n}\n\nconst getCookieValue = (ctx: OAuthCtx, name: string): string | null => {\n const header = ctx.req.headers?.cookie\n if (typeof header !== \"string\" || !header) return null\n\n for (const part of header.split(\";\")) {\n const [rawKey, ...rest] = part.split(\"=\")\n const key = rawKey?.trim()\n if (!key || key !== name) continue\n const rawValue = rest.join(\"=\").trim()\n if (!rawValue) return \"\"\n try {\n return decodeURIComponent(rawValue)\n } catch {\n return rawValue\n }\n }\n\n return null\n}\n\nconst isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n}\n\nconst getRequestOrigin = (ctx: OAuthCtx) => {\n const protoHeader = ctx.req.headers[\"x-forwarded-proto\"]\n const hostHeader = ctx.req.headers[\"x-forwarded-host\"]\n\n const protocol = typeof protoHeader === \"string\"\n ? protoHeader.split(\",\")[0].trim()\n : ctx.req.protocol\n\n const host = typeof hostHeader === \"string\"\n ? hostHeader.split(\",\")[0].trim()\n : ctx.req.get(\"host\")\n\n return protocol && host ? `${protocol}://${host}` : \"\"\n}\n\nconst resolveCallbackPath = (callbackPath: string) => {\n const trimmed = callbackPath.trim()\n return trimmed && isSafeRedirectPath(trimmed) ? trimmed : null\n}\n\nconst readTextBody = async (req: Pick<OAuthCtx[\"req\"], \"on\" | \"setEncoding\">) =>\n await new Promise<string>((resolve, reject) => {\n let body = \"\"\n if (typeof req.setEncoding === \"function\") {\n req.setEncoding(\"utf8\")\n }\n\n req.on(\"data\", (chunk) => {\n body += String(chunk)\n if (body.length > 32_768) {\n reject(new Error(\"request_body_too_large\"))\n }\n })\n req.on(\"end\", () => resolve(body))\n req.on(\"error\", reject)\n })\n\nconst getFormPostParams = async (ctx: OAuthCtx): Promise<Record<string, string> | null> => {\n if (ctx.req.method !== \"POST\") return null\n\n const contentType = typeof ctx.req.headers[\"content-type\"] === \"string\" ? ctx.req.headers[\"content-type\"] : \"\"\n if (!contentType.includes(\"application/x-www-form-urlencoded\")) return null\n\n const body = await readTextBody(ctx.req)\n const params = new URLSearchParams(body)\n\n const result: Record<string, string> = {}\n for (const [key, value] of params.entries()) {\n result[key] = value\n }\n\n return result\n}\n\nconst resolveProviderId = (ctx: OAuthCtx, providerIdOverride?: string) =>\n (providerIdOverride ?? String(ctx.req.params?.provider ?? \"\")).trim()\n\nconst RESERVED_AUTH_PARAM_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nconst normalizeAuthorizationParams = (value: unknown): Record<string, string> | undefined => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined\n\n const result: Record<string, string> = {}\n for (const [keyRaw, valueRaw] of Object.entries(value)) {\n const key = keyRaw.trim()\n if (!key) continue\n if (RESERVED_AUTH_PARAM_KEYS.has(key)) continue\n const val = typeof valueRaw === \"string\" ? valueRaw.trim() : \"\"\n if (!val) continue\n result[key] = val\n }\n\n return Object.keys(result).length ? result : undefined\n}\n\nexport type OAuthStartResult =\n | { success: true; redirectUrl: string }\n | { success: false; error: string; statusCode: number }\n\nexport const getOAuthStartRedirectUrl = async ({\n ctx,\n providerId: providerIdOverride,\n returnTo,\n authorizationParams,\n}: {\n ctx: OAuthCtx\n providerId?: string\n returnTo?: string | null\n authorizationParams?: Record<string, string>\n}): Promise<OAuthStartResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, error: \"missing_provider\", statusCode: 400 }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, error: \"invalid_provider\", statusCode: 400 }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, error: \"unknown_provider\", statusCode: 404 }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, error: \"origin_unavailable\", statusCode: 500 }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, error: \"invalid_callback_path\", statusCode: 500 }\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\")\n const { verifier, challenge } = generatePkcePair()\n\n const safeReturnTo = typeof returnTo === \"string\" && isSafeRedirectPath(returnTo) ? returnTo : undefined\n\n try {\n const OAuthRequest = await models.getGlobal(\"RBOAuthRequest\", ctx)\n const now = new Date()\n await OAuthRequest.create({\n _id: state,\n providerId,\n codeVerifier: verifier,\n returnTo: safeReturnTo,\n createdAt: now,\n expiresAt: new Date(now.getTime() + OAUTH_REQUEST_TTL_MS),\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_store_request\", err)\n return { success: false, error: \"oauth_request_store_failed\", statusCode: 500 }\n }\n\n try {\n ctx.res.cookie(OAUTH_STATE_COOKIE_NAME, `${providerId}:${state}`, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n maxAge: OAUTH_REQUEST_TTL_MS,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_set_state_cookie\", err)\n return { success: false, error: \"oauth_cookie_set_failed\", statusCode: 500 }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const url = new URL(oidc.authorization_endpoint)\n url.searchParams.set(\"client_id\", provider.clientId)\n url.searchParams.set(\"redirect_uri\", redirectUri)\n url.searchParams.set(\"response_type\", \"code\")\n url.searchParams.set(\"scope\", provider.scope)\n url.searchParams.set(\"state\", state)\n url.searchParams.set(\"code_challenge\", challenge)\n url.searchParams.set(\"code_challenge_method\", \"S256\")\n const extraAuthorizationParams = normalizeAuthorizationParams(authorizationParams)\n for (const [key, value] of Object.entries(extraAuthorizationParams ?? {})) {\n if (url.searchParams.has(key)) continue\n url.searchParams.set(key, value)\n }\n\n return { success: true, redirectUrl: url.toString() }\n}\n\nexport type OAuthCallbackResult =\n | {\n success: true\n type: \"signed_in\"\n redirectPath: string\n userId: string\n tenantId: string\n signedInTenants: string[]\n }\n | {\n success: false\n type: \"missing_user\"\n providerId: string\n subject: string\n email?: string\n name?: string\n redirectPath?: string\n }\n | {\n success: false\n type: \"error\"\n error: string\n redirectPath: string\n }\n\nconst OAUTH_SUCCESS_REDIRECT_PATH = \"/onboarding\"\nconst AUTH_ERROR_REDIRECT_BASE = \"/auth/sign-in\"\n\nexport const processOAuthCallback = async ({\n ctx,\n providerId: providerIdOverride,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n ctx: OAuthCtx\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n}): Promise<OAuthCallbackResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, type: \"error\", error: \"missing_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_provider` }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, type: \"error\", error: \"invalid_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_provider` }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, type: \"error\", error: \"unknown_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, type: \"error\", error: \"origin_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, type: \"error\", error: \"invalid_callback_path\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` }\n }\n\n const bodyParams = await getFormPostParams(ctx)\n\n const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? \"\"\n const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? \"\"\n const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? \"\"\n\n if (!code || !state) {\n return { success: false, type: \"error\", error: \"missing_code_or_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` }\n }\n\n const stateCookieValue = getCookieValue(ctx, OAUTH_STATE_COOKIE_NAME)\n if (stateCookieValue !== `${providerId}:${state}`) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n let oauthRequest: OAuthRequestRecord | null = null\n let OAuthRequestModel: Awaited<ReturnType<typeof models.getGlobal>> | null = null\n try {\n OAuthRequestModel = await models.getGlobal(\"RBOAuthRequest\", ctx)\n oauthRequest = await OAuthRequestModel.findOne({ _id: state, providerId }).lean() as OAuthRequestRecord | null\n } catch (err) {\n console.warn(\"oauth::failed_to_load_request\", err)\n return { success: false, type: \"error\", error: \"oauth_request_load_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=oauth_request_load_failed` }\n }\n\n if (!oauthRequest) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n const returnTo = typeof oauthRequest.returnTo === \"string\" ? oauthRequest.returnTo : undefined\n const codeVerifier = typeof oauthRequest.codeVerifier === \"string\" ? oauthRequest.codeVerifier : \"\"\n if (!codeVerifier) {\n return { success: false, type: \"error\", error: \"missing_code_verifier\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const tokenBody = new URLSearchParams()\n tokenBody.set(\"grant_type\", \"authorization_code\")\n tokenBody.set(\"code\", code)\n tokenBody.set(\"redirect_uri\", redirectUri)\n tokenBody.set(\"client_id\", provider.clientId)\n tokenBody.set(\"code_verifier\", codeVerifier)\n if (provider.clientSecret) {\n tokenBody.set(\"client_secret\", provider.clientSecret)\n }\n\n const tokenResponse = await fetch(oidc.token_endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: tokenBody.toString(),\n })\n\n const tokenJson = await tokenResponse.json().catch(() => null) as Record<string, unknown> | null\n\n if (!tokenResponse.ok || !tokenJson || typeof tokenJson !== \"object\") {\n const body = tokenJson ? JSON.stringify(tokenJson) : \"\"\n console.warn(\"oauth::token_exchange failed\", tokenResponse.status, body)\n return { success: false, type: \"error\", error: \"token_exchange_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=token_exchange_failed` }\n }\n\n const accessToken = typeof tokenJson.access_token === \"string\" ? tokenJson.access_token : \"\"\n const refreshToken = typeof tokenJson.refresh_token === \"string\" ? tokenJson.refresh_token : undefined\n const idToken = typeof tokenJson.id_token === \"string\" ? tokenJson.id_token : undefined\n const scope = typeof tokenJson.scope === \"string\" ? tokenJson.scope : undefined\n const tokenType = typeof tokenJson.token_type === \"string\" ? tokenJson.token_type : undefined\n const expiresIn = typeof tokenJson.expires_in === \"number\"\n ? tokenJson.expires_in\n : typeof tokenJson.expires_in === \"string\"\n ? Number(tokenJson.expires_in)\n : undefined\n const expiresInSeconds = typeof expiresIn === \"number\" && Number.isFinite(expiresIn) ? expiresIn : null\n const expiresAt = expiresInSeconds !== null ? new Date(Date.now() + expiresInSeconds * 1000) : undefined\n\n let userInfo: Record<string, unknown> | null = null\n\n if (oidc.userinfo_endpoint && accessToken) {\n const userInfoResponse = await fetch(oidc.userinfo_endpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n })\n\n if (userInfoResponse.ok) {\n userInfo = await userInfoResponse.json().catch(() => null) as Record<string, unknown> | null\n }\n }\n\n const idTokenPayload = idToken ? decodeJwtPayload<Record<string, unknown>>(idToken) : null\n const accessTokenPayload = decodeJwtPayload<Record<string, unknown>>(accessToken)\n\n const subject = typeof userInfo?.sub === \"string\"\n ? userInfo.sub\n : typeof idTokenPayload?.sub === \"string\"\n ? idTokenPayload.sub\n : typeof accessTokenPayload?.sub === \"string\"\n ? accessTokenPayload.sub\n : \"\"\n\n if (!subject) {\n return { success: false, type: \"error\", error: \"missing_subject\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_subject` }\n }\n\n const email = typeof userInfo?.email === \"string\"\n ? userInfo.email\n : typeof idTokenPayload?.email === \"string\"\n ? idTokenPayload.email\n : undefined\n\n const name = typeof userInfo?.name === \"string\"\n ? userInfo.name\n : typeof idTokenPayload?.name === \"string\"\n ? idTokenPayload.name\n : undefined\n\n let oauthUser: unknown = null\n if (oauthUserRaw) {\n try {\n oauthUser = JSON.parse(oauthUserRaw) as unknown\n } catch {\n oauthUser = null\n }\n }\n const oauthUserRecord = oauthUser && typeof oauthUser === \"object\"\n ? (oauthUser as Record<string, unknown>)\n : null\n const oauthUserEmail = typeof oauthUserRecord?.email === \"string\" ? oauthUserRecord.email.trim() : \"\"\n const oauthUserNameRecord = oauthUserRecord?.name && typeof oauthUserRecord.name === \"object\"\n ? (oauthUserRecord.name as Record<string, unknown>)\n : null\n const oauthUserNameFirst = typeof oauthUserNameRecord?.firstName === \"string\" ? oauthUserNameRecord.firstName.trim() : \"\"\n const oauthUserNameLast = typeof oauthUserNameRecord?.lastName === \"string\" ? oauthUserNameRecord.lastName.trim() : \"\"\n const oauthUserName = [oauthUserNameFirst, oauthUserNameLast].filter(Boolean).join(\" \").trim()\n\n const resolvedEmail = email ?? (oauthUserEmail || undefined)\n const resolvedName = name ?? (oauthUserName || undefined)\n\n const [User, Tenant] = await Promise.all([\n models.getGlobal(\"RBUser\", ctx),\n models.getGlobal(\"RBTenant\", ctx),\n ])\n\n const subjectQueryKey = `oauthProviders.${providerId}.subject`\n let user = await User.findOne({ [subjectQueryKey]: subject })\n\n if (!user && resolvedEmail) {\n user = await User.findOne({ email: resolvedEmail })\n }\n\n const shouldCreateUser = createUserOnFirstSignIn ?? true\n if (!user && !shouldCreateUser) {\n const redirectPath = missingUserRedirectPath\n\n const result: OAuthCallbackResult = {\n success: false,\n type: \"missing_user\",\n providerId,\n subject,\n email: resolvedEmail,\n name: resolvedName,\n }\n\n if (redirectPath && isSafeRedirectPath(redirectPath)) {\n const url = new URL(redirectPath, origin)\n url.searchParams.set(\"oauth_provider\", providerId)\n if (resolvedEmail) url.searchParams.set(\"email\", resolvedEmail)\n if (resolvedName) url.searchParams.set(\"name\", resolvedName)\n result.redirectPath = `${url.pathname}${url.search}`\n }\n\n return result\n }\n\n if (!ctx.req.session) {\n return { success: false, type: \"error\", error: \"session_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` }\n }\n\n const now = new Date()\n\n let providerCreatedAt: Date | undefined\n const oauthProviders = user?.get(\"oauthProviders\") as Map<string, { createdAt?: unknown }> | undefined\n const existingProvider = oauthProviders?.get(providerId)\n if (existingProvider?.createdAt instanceof Date) {\n providerCreatedAt = existingProvider.createdAt\n }\n\n const oauthProviderPayload = {\n subject,\n email: resolvedEmail,\n name: resolvedName,\n accessToken,\n refreshToken,\n idToken,\n scope,\n tokenType,\n expiresAt,\n rawUserInfo: userInfo ?? undefined,\n createdAt: providerCreatedAt ?? now,\n updatedAt: now,\n }\n\n if (!user) {\n const tenantId = crypto.randomUUID()\n const password = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n\n user = new User({\n email: resolvedEmail,\n name: resolvedName,\n password,\n tenants: [tenantId],\n tenantRoles: {\n [tenantId]: [\"owner\"],\n },\n oauthProviders: {\n [providerId]: oauthProviderPayload,\n },\n })\n\n await user.save()\n\n try {\n await Tenant.create({\n tenantId,\n name: resolvedEmail || subject,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_create_tenant\", err)\n }\n } else {\n const setFields: Record<string, unknown> = {\n [`oauthProviders.${providerId}`]: oauthProviderPayload,\n }\n\n if (!user.email && resolvedEmail) {\n setFields.email = resolvedEmail\n }\n\n if (!user.name && resolvedName) {\n setFields.name = resolvedName\n }\n\n await User.updateOne({ _id: user._id }, { $set: setFields })\n }\n\n const signedInTenants = (user.tenants || []).map(String)\n const tenantId = signedInTenants[0]\n if (!tenantId) {\n return {\n success: false,\n type: \"error\",\n error: \"tenant_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`,\n }\n }\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!completeAuthSignIn(ctx, {\n userId: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n tenantRoles,\n })) {\n return {\n success: false,\n type: \"error\",\n error: \"session_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable`,\n }\n }\n\n try {\n if (OAuthRequestModel) {\n await OAuthRequestModel.deleteOne({ _id: state, providerId })\n }\n } catch (err) {\n console.warn(\"oauth::failed_to_delete_request\", err)\n }\n\n try {\n ctx.res.clearCookie(OAUTH_STATE_COOKIE_NAME, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_clear_state_cookie\", err)\n }\n\n const redirectPath = returnTo && isSafeRedirectPath(returnTo)\n ? returnTo\n : successRedirectPath && isSafeRedirectPath(successRedirectPath)\n ? successRedirectPath\n : OAUTH_SUCCESS_REDIRECT_PATH\n\n return {\n success: true,\n type: \"signed_in\",\n redirectPath,\n userId: user._id.toString(),\n tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n }\n}\n\nexport const createOAuthStartHandler = ({\n providerId,\n getAuthorizationParams,\n}: {\n providerId?: string\n getAuthorizationParams?: (providerId: string) => Record<string, string> | undefined\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const resolvedProviderId = resolveProviderId(ctx, providerId)\n const providerAuthorizationParams = resolvedProviderId && getAuthorizationParams\n ? getAuthorizationParams(resolvedProviderId)\n : undefined\n const returnTo = getQueryString(ctx.req.query?.returnTo)?.trim()\n const result = await getOAuthStartRedirectUrl({\n ctx,\n providerId: resolvedProviderId,\n returnTo,\n authorizationParams: providerAuthorizationParams,\n })\n\n if (!result.success) {\n ctx.res.status(result.statusCode)\n return { success: false, error: result.error }\n }\n\n ctx.res.redirect(result.redirectUrl)\n return { success: true }\n}\n\nexport const createOAuthCallbackHandler = ({\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const result = await processOAuthCallback({\n ctx,\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n })\n\n if (result.type === \"error\") {\n ctx.res.redirect(result.redirectPath)\n return { success: false, error: result.error }\n }\n\n if (result.type === \"missing_user\") {\n if (result.redirectPath) {\n ctx.res.redirect(result.redirectPath)\n } else {\n ctx.res.redirect(\"/auth/sign-up\")\n }\n return { success: false, error: \"user_not_found\" }\n }\n\n ctx.res.redirect(result.redirectPath)\n return { success: true }\n}\n\nconst base64UrlEncode = (input: Buffer | string) =>\n Buffer.from(input)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const createAppleClientSecret = ({\n teamId,\n clientId,\n keyId,\n privateKeyPem,\n now = new Date(),\n expiresInSeconds = 10 * 60,\n}: {\n teamId: string\n clientId: string\n keyId: string\n privateKeyPem: string\n now?: Date\n expiresInSeconds?: number\n}) => {\n const teamIdValue = teamId.trim()\n const clientIdValue = clientId.trim()\n const keyIdValue = keyId.trim()\n const privateKeyPemValue = privateKeyPem.trim()\n\n if (!teamIdValue) throw new Error(\"teamId is required\")\n if (!clientIdValue) throw new Error(\"clientId is required\")\n if (!keyIdValue) throw new Error(\"keyId is required\")\n if (!privateKeyPemValue) throw new Error(\"privateKeyPem is required\")\n\n const nowSeconds = Math.floor(now.getTime() / 1000)\n const expiresIn = Number.isFinite(expiresInSeconds) ? expiresInSeconds : 10 * 60\n const exp = nowSeconds + Math.max(60, Math.min(expiresIn, 60 * 60 * 24 * 180))\n\n const header = { alg: \"ES256\", kid: keyIdValue, typ: \"JWT\" }\n const payload = {\n iss: teamIdValue,\n iat: nowSeconds,\n exp,\n aud: \"https://appleid.apple.com\",\n sub: clientIdValue,\n }\n\n const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`\n const signature = crypto.sign(\"sha256\", Buffer.from(signingInput), {\n key: privateKeyPemValue,\n dsaEncoding: \"ieee-p1363\",\n })\n\n return `${signingInput}.${base64UrlEncode(signature)}`\n}\n"],"names":["STORE_KEY","Symbol","for","getStore","anyGlobal","globalThis","existing","providers","created","normalizeProviders","result","isSafeRedirectPath","candidate","startsWith","providerIdRaw","value","Object","entries","providerId","trim","issuer","clientId","Error","clientSecret","undefined","scope","callbackPath","configureOAuthProviders","store","normalized","setOAuthProviders","getOAuthProviderConfig","decodeBase64Url","padded","replace","slice","length","Buffer","from","toString","decodeJwtPayload","token","parts","split","json","parsed","JSON","parse","cache","Map","normalizeIssuer","raw","getOidcWellKnown","issuerRaw","get","loader","url","URL","response","fetch","headers","Accept","ok","body","text","catch","status","authorizationEndpoint","authorization_endpoint","tokenEndpoint","token_endpoint","issuerValue","userinfoEndpoint","userinfo_endpoint","jwksUri","jwks_uri","set","err","delete","base64UrlEncode","input","generatePkcePair","verifier","crypto","randomBytes","challenge","createHash","update","digest","RESERVED_KEYS","Set","isSafeOAuthProviderId","has","test","OAUTH_REQUEST_TTL_MS","OAUTH_STATE_COOKIE_NAME","getQueryString","Array","isArray","getCookieValue","ctx","name","header","req","cookie","part","rawKey","rest","key","rawValue","join","decodeURIComponent","getRequestOrigin","protoHeader","hostHeader","protocol","host","resolveCallbackPath","trimmed","readTextBody","Promise","resolve","reject","setEncoding","on","chunk","String","getFormPostParams","method","contentType","includes","params","URLSearchParams","resolveProviderId","providerIdOverride","provider","RESERVED_AUTH_PARAM_KEYS","normalizeAuthorizationParams","keyRaw","valueRaw","val","keys","getOAuthStartRedirectUrl","returnTo","authorizationParams","success","error","statusCode","origin","isHttps","state","safeReturnTo","OAuthRequest","models","getGlobal","now","Date","create","_id","codeVerifier","createdAt","expiresAt","getTime","console","warn","res","httpOnly","secure","sameSite","path","maxAge","oidc","redirectUri","searchParams","extraAuthorizationParams","redirectUrl","OAUTH_SUCCESS_REDIRECT_PATH","AUTH_ERROR_REDIRECT_BASE","processOAuthCallback","createUserOnFirstSignIn","missingUserRedirectPath","successRedirectPath","type","redirectPath","bodyParams","code","query","oauthUserRaw","user","stateCookieValue","oauthRequest","OAuthRequestModel","findOne","lean","tokenBody","tokenResponse","tokenJson","stringify","accessToken","access_token","refreshToken","refresh_token","idToken","id_token","tokenType","token_type","expiresIn","expires_in","Number","expiresInSeconds","isFinite","userInfo","userInfoResponse","Authorization","idTokenPayload","accessTokenPayload","subject","sub","email","oauthUser","oauthUserRecord","oauthUserEmail","oauthUserNameRecord","oauthUserNameFirst","firstName","oauthUserNameLast","lastName","oauthUserName","filter","Boolean","resolvedEmail","resolvedName","User","Tenant","all","subjectQueryKey","shouldCreateUser","pathname","search","session","providerCreatedAt","oauthProviders","existingProvider","oauthProviderPayload","rawUserInfo","updatedAt","tenantId","randomUUID","password","hashPasswordForStorage","tenants","tenantRoles","save","setFields","updateOne","$set","signedInTenants","map","tenantRolesMap","fromEntries","completeAuthSignIn","userId","currentTenantId","deleteOne","clearCookie","createOAuthStartHandler","getAuthorizationParams","_payload","resolvedProviderId","providerAuthorizationParams","redirect","createOAuthCallbackHandler","createAppleClientSecret","teamId","keyId","privateKeyPem","teamIdValue","clientIdValue","keyIdValue","privateKeyPemValue","nowSeconds","Math","floor","exp","max","min","alg","kid","typ","payload","iss","iat","aud","signingInput","signature","sign","dsaEncoding"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/oauth/lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/oauth/lib.ts"],"names":[],"mappings":"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"}
package/dist/routes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const routes = Object.entries({
2
- .../* @__PURE__ */ Object.assign({ "./api/me/handler.ts": () => import("./handler-D7KnXlx3.js"), "./api/request-password-reset/handler.ts": () => import("./handler-BNDemOGd.js"), "./api/resend-otp/handler.ts": () => import("./handler-Bt53h0sk.js"), "./api/set-new-password/handler.ts": () => import("./handler-C4cw739Z.js"), "./api/sign-in/handler.ts": () => import("./handler-DfEsSB4T.js"), "./api/sign-out/handler.ts": () => import("./handler-CyP6R8FM.js"), "./api/sign-up/handler.ts": () => import("./handler-D6zJn86A.js"), "./api/verify-otp/handler.ts": () => import("./handler-Ck7oLQ_R.js"), "./api/verify-password-reset-otp/handler.ts": () => import("./handler-D8HfTbUs.js") })
2
+ .../* @__PURE__ */ Object.assign({ "./api/me/handler.ts": () => import("./handler-CbSJDqWW.js"), "./api/request-password-reset/handler.ts": () => import("./handler-BNDemOGd.js"), "./api/resend-otp/handler.ts": () => import("./handler-Bt53h0sk.js"), "./api/set-active-account/handler.ts": () => import("./handler-VH4B70Zr.js"), "./api/set-new-password/handler.ts": () => import("./handler-C4cw739Z.js"), "./api/sign-in/handler.ts": () => import("./handler-B5I4pH46.js"), "./api/sign-out/handler.ts": () => import("./handler-CyP6R8FM.js"), "./api/sign-up/handler.ts": () => import("./handler-D6zJn86A.js"), "./api/verify-otp/handler.ts": () => import("./handler-gfRB07A8.js"), "./api/verify-password-reset-otp/handler.ts": () => import("./handler-D8HfTbUs.js") })
3
3
  }).reduce((acc, [path, mod]) => {
4
4
  acc[path.replace("./api/", "@rpcbase/auth/api/")] = mod;
5
5
  return acc;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sources":["../src/routes.ts"],"sourcesContent":["export const routes = Object.entries({\n ...import.meta.glob(\"./api/**/handler.ts\"),\n}).reduce<Record<string, unknown>>((acc, [path, mod]) => {\n // re-add package name in front of the path so we know which are the framework routes vs app routes\n acc[path.replace(\"./api/\", \"@rpcbase/auth/api/\")] = mod\n return acc\n}, {})\n"],"names":["routes","Object","entries","import","reduce","acc","path","mod","replace"],"mappings":"AAAO,MAAMA,SAASC,OAAOC,QAAQ;AAAA,EACnC,GAAGC,uBAAAA,OAAAA,EAAAA,uBAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,2CAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,+BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,qCAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,4BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,6BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,4BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,+BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,8CAAAA,MAAAA,OAAAA,uBAAAA,EAAAA,CAAAA;AACL,CAAC,EAAEC,OAAgC,CAACC,KAAK,CAACC,MAAMC,GAAG,MAAM;AAEvDF,MAAIC,KAAKE,QAAQ,UAAU,oBAAoB,CAAC,IAAID;AACpD,SAAOF;AACT,GAAG,CAAA,CAAE;"}
1
+ {"version":3,"file":"routes.js","sources":["../src/routes.ts"],"sourcesContent":["export const routes = Object.entries({\n ...import.meta.glob(\"./api/**/handler.ts\"),\n}).reduce<Record<string, unknown>>((acc, [path, mod]) => {\n // re-add package name in front of the path so we know which are the framework routes vs app routes\n acc[path.replace(\"./api/\", \"@rpcbase/auth/api/\")] = mod\n return acc\n}, {})\n"],"names":["routes","Object","entries","import","reduce","acc","path","mod","replace"],"mappings":"AAAO,MAAMA,SAASC,OAAOC,QAAQ;AAAA,EACnC,GAAGC,uBAAAA,OAAAA,EAAAA,uBAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,2CAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,+BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,uCAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,qCAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,4BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,6BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,4BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,+BAAAA,MAAAA,OAAAA,uBAAAA,GAAAA,8CAAAA,MAAAA,OAAAA,uBAAAA,EAAAA,CAAAA;AACL,CAAC,EAAEC,OAAgC,CAACC,KAAK,CAACC,MAAMC,GAAG,MAAM;AAEvDF,MAAIC,KAAKE,QAAQ,UAAU,oBAAoB,CAAC,IAAID;AACpD,SAAOF;AACT,GAAG,CAAA,CAAE;"}
@@ -0,0 +1,20 @@
1
+ const AUTHENTICATED_USER_ID_HEADER = "rb-authenticated-user-id";
2
+ const AUTHENTICATED_TENANT_ID_HEADER = "rb-authenticated-tenant-id";
3
+ const completeAuthSignIn = (ctx, args) => {
4
+ if (!ctx.req.session) return false;
5
+ ctx.req.session.user = {
6
+ id: args.userId,
7
+ currentTenantId: args.currentTenantId,
8
+ signedInTenants: args.signedInTenants,
9
+ isEntryGateAuthorized: true,
10
+ tenantRoles: args.tenantRoles
11
+ };
12
+ ctx.res.setHeader(AUTHENTICATED_USER_ID_HEADER, args.userId);
13
+ ctx.res.setHeader(AUTHENTICATED_TENANT_ID_HEADER, args.currentTenantId);
14
+ return true;
15
+ };
16
+ export {
17
+ AUTHENTICATED_TENANT_ID_HEADER as A,
18
+ completeAuthSignIn as c
19
+ };
20
+ //# sourceMappingURL=session-DoTNxRRA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-DoTNxRRA.js","sources":["../src/session.ts"],"sourcesContent":["import type { Ctx } from \"@rpcbase/api\"\n\nimport type { AuthSessionUser } from \"./types\"\n\n\nexport const AUTHENTICATED_USER_ID_HEADER = \"rb-authenticated-user-id\"\nexport const AUTHENTICATED_TENANT_ID_HEADER = \"rb-authenticated-tenant-id\"\n\ntype CompleteAuthSignInArgs = {\n userId: string\n currentTenantId: string\n signedInTenants: string[]\n tenantRoles?: Record<string, string[]>\n}\n\nexport const completeAuthSignIn = (\n ctx: Ctx<AuthSessionUser>,\n args: CompleteAuthSignInArgs,\n): boolean => {\n if (!ctx.req.session) return false\n\n ctx.req.session.user = {\n id: args.userId,\n currentTenantId: args.currentTenantId,\n signedInTenants: args.signedInTenants,\n isEntryGateAuthorized: true,\n tenantRoles: args.tenantRoles,\n }\n\n ctx.res.setHeader(AUTHENTICATED_USER_ID_HEADER, args.userId)\n ctx.res.setHeader(AUTHENTICATED_TENANT_ID_HEADER, args.currentTenantId)\n\n return true\n}\n"],"names":["AUTHENTICATED_USER_ID_HEADER","AUTHENTICATED_TENANT_ID_HEADER","completeAuthSignIn","ctx","args","req","session","user","id","userId","currentTenantId","signedInTenants","isEntryGateAuthorized","tenantRoles","res","setHeader"],"mappings":"AAKO,MAAMA,+BAA+B;AACrC,MAAMC,iCAAiC;AASvC,MAAMC,qBAAqBA,CAChCC,KACAC,SACY;AACZ,MAAI,CAACD,IAAIE,IAAIC,QAAS,QAAO;AAE7BH,MAAIE,IAAIC,QAAQC,OAAO;AAAA,IACrBC,IAAIJ,KAAKK;AAAAA,IACTC,iBAAiBN,KAAKM;AAAAA,IACtBC,iBAAiBP,KAAKO;AAAAA,IACtBC,uBAAuB;AAAA,IACvBC,aAAaT,KAAKS;AAAAA,EAAAA;AAGpBV,MAAIW,IAAIC,UAAUf,8BAA8BI,KAAKK,MAAM;AAC3DN,MAAIW,IAAIC,UAAUd,gCAAgCG,KAAKM,eAAe;AAEtE,SAAO;AACT;"}
@@ -0,0 +1,13 @@
1
+ import { Ctx } from '@rpcbase/api';
2
+ import { AuthSessionUser } from './types';
3
+ export declare const AUTHENTICATED_USER_ID_HEADER = "rb-authenticated-user-id";
4
+ export declare const AUTHENTICATED_TENANT_ID_HEADER = "rb-authenticated-tenant-id";
5
+ type CompleteAuthSignInArgs = {
6
+ userId: string;
7
+ currentTenantId: string;
8
+ signedInTenants: string[];
9
+ tenantRoles?: Record<string, string[]>;
10
+ };
11
+ export declare const completeAuthSignIn: (ctx: Ctx<AuthSessionUser>, args: CompleteAuthSignInArgs) => boolean;
12
+ export {};
13
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAG9C,eAAO,MAAM,4BAA4B,6BAA6B,CAAA;AACtE,eAAO,MAAM,8BAA8B,+BAA+B,CAAA;AAE1E,KAAK,sBAAsB,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,KAAK,GAAG,CAAC,eAAe,CAAC,EACzB,MAAM,sBAAsB,KAC3B,OAeF,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/auth",
3
- "version": "0.123.0",
3
+ "version": "0.125.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler-Ck7oLQ_R.js","sources":["../src/api/verify-otp/index.ts","../src/api/verify-otp/handler.ts"],"sourcesContent":["import { z } from \"zod\"\n\n\nexport const Route = \"/api/rb/auth/verify-otp\"\n\nexport const requestSchema = z.object({\n email: z.string().email(),\n code: z.string().length(6, \"Code must be 6 digits\"),\n rememberMe: z.boolean().default(true),\n})\n\nexport type RequestPayload = z.infer<typeof requestSchema>\n\nexport const responseSchema = z.object({\n success: z.boolean(),\n error: z.string().optional(),\n userId: z.string().optional(),\n tenantId: z.string().optional(),\n})\n\nexport type ResponsePayload = z.infer<typeof responseSchema>\n","import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\n\nimport type { AuthSessionUser } from \"../../types\"\n\nimport * as VerifyOtp from \"./index\"\n\n\nconst verifyOtp: ApiHandler<VerifyOtp.RequestPayload, VerifyOtp.ResponsePayload, AuthSessionUser> = async (\n payload,\n ctx: Ctx<AuthSessionUser>\n): Promise<VerifyOtp.ResponsePayload> => {\n const User = await models.getGlobal(\"RBUser\", ctx)\n\n const parsed = VerifyOtp.requestSchema.safeParse(payload)\n\n if (!parsed.success) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_payload\" }\n }\n\n const { email, code } = parsed.data\n\n const user = await User.findOne({ email }, { emailVerificationCode: 1, emailVerificationExpiresAt: 1, tenants: 1, tenantRoles: 1 })\n\n if (!user) {\n ctx.res.status(404)\n return { success: false, error: \"user_not_found\" }\n }\n\n const storedCode = user.emailVerificationCode\n const expiresAt = user.emailVerificationExpiresAt\n\n const isExpired = expiresAt instanceof Date && expiresAt.getTime() < Date.now()\n if (!storedCode || storedCode !== code || isExpired) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_code\" }\n }\n\n user.emailVerificationCode = undefined\n user.emailVerificationExpiresAt = undefined\n await user.save()\n\n const tenantId = user.tenants?.[0]?.toString?.() || \"00000000\"\n const signedInTenants = (user.tenants || []).map(String)\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!ctx.req.session) {\n ctx.res.status(500)\n return { success: false, error: \"session_unavailable\" }\n }\n\n ctx.req.session.user = {\n id: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n isEntryGateAuthorized: true,\n tenantRoles,\n }\n\n return { success: true, userId: user._id.toString(), tenantId }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.post(VerifyOtp.Route, verifyOtp)\n}\n"],"names":["Route","requestSchema","z","email","string","code","length","rememberMe","default","success","boolean","error","optional","userId","tenantId","verifyOtp","payload","ctx","User","models","getGlobal","parsed","VerifyOtp","safeParse","res","status","data","user","findOne","emailVerificationCode","emailVerificationExpiresAt","tenants","tenantRoles","storedCode","expiresAt","isExpired","Date","getTime","now","undefined","save","toString","signedInTenants","map","String","tenantRolesMap","get","Object","fromEntries","entries","req","session","id","_id","currentTenantId","isEntryGateAuthorized","api","post"],"mappings":";;AAGO,MAAMA,QAAQ;AAEd,MAAMC,gBAAgBC,OAAS;AAAA,EACpCC,OAAOD,OAAEE,EAASD,MAAAA;AAAAA,EAClBE,MAAMH,OAAEE,EAASE,OAAO,GAAG,uBAAuB;AAAA,EAClDC,YAAYL,UAAYM,QAAQ,IAAI;AACtC,CAAC;AAI6BN,OAAS;AAAA,EACrCO,SAASP,QAAEQ;AAAAA,EACXC,OAAOT,OAAEE,EAASQ,SAAAA;AAAAA,EAClBC,QAAQX,OAAEE,EAASQ,SAAAA;AAAAA,EACnBE,UAAUZ,OAAEE,EAASQ,SAAAA;AACvB,CAAC;ACVD,MAAMG,YAA8F,OAClGC,SACAC,QACuC;AACvC,QAAMC,OAAO,MAAMC,OAAOC,UAAU,UAAUH,GAAG;AAEjD,QAAMI,SAASC,cAAwBC,UAAUP,OAAO;AAExD,MAAI,CAACK,OAAOZ,SAAS;AACnBQ,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAM;AAAA,IAAER;AAAAA,IAAOE;AAAAA,EAAAA,IAASgB,OAAOK;AAE/B,QAAMC,OAAO,MAAMT,KAAKU,QAAQ;AAAA,IAAEzB;AAAAA,EAAAA,GAAS;AAAA,IAAE0B,uBAAuB;AAAA,IAAGC,4BAA4B;AAAA,IAAGC,SAAS;AAAA,IAAGC,aAAa;AAAA,EAAA,CAAG;AAElI,MAAI,CAACL,MAAM;AACTV,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMsB,aAAaN,KAAKE;AACxB,QAAMK,YAAYP,KAAKG;AAEvB,QAAMK,YAAYD,qBAAqBE,QAAQF,UAAUG,QAAAA,IAAYD,KAAKE,IAAAA;AAC1E,MAAI,CAACL,cAAcA,eAAe5B,QAAQ8B,WAAW;AACnDlB,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEAgB,OAAKE,wBAAwBU;AAC7BZ,OAAKG,6BAA6BS;AAClC,QAAMZ,KAAKa,KAAAA;AAEX,QAAM1B,WAAWa,KAAKI,UAAU,CAAC,GAAGU,gBAAgB;AACpD,QAAMC,mBAAmBf,KAAKI,WAAW,CAAA,GAAIY,IAAIC,MAAM;AACvD,QAAMC,iBAAiBlB,KAAKmB,IAAI,aAAa;AAC7C,QAAMd,cAAca,iBAAiBE,OAAOC,YAAYH,eAAeI,QAAAA,CAAS,IAAIV;AAEpF,MAAI,CAACtB,IAAIiC,IAAIC,SAAS;AACpBlC,QAAIO,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEhB,SAAS;AAAA,MAAOE,OAAO;AAAA,IAAA;AAAA,EAClC;AAEAM,MAAIiC,IAAIC,QAAQxB,OAAO;AAAA,IACrByB,IAAIzB,KAAK0B,IAAIZ,SAAAA;AAAAA,IACba,iBAAiBxC;AAAAA,IACjB4B,iBAAiBA,gBAAgBpC,SAASoC,kBAAkB,CAAC5B,QAAQ;AAAA,IACrEyC,uBAAuB;AAAA,IACvBvB;AAAAA,EAAAA;AAGF,SAAO;AAAA,IAAEvB,SAAS;AAAA,IAAMI,QAAQc,KAAK0B,IAAIZ,SAAAA;AAAAA,IAAY3B;AAAAA,EAAAA;AACvD;AAEA,MAAA,UAAe,CAAC0C,QAA8B;AAC5CA,MAAIC,KAAKnC,OAAiBP,SAAS;AACrC;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler-D7KnXlx3.js","sources":["../src/api/me/index.ts","../src/api/me/handler.ts"],"sourcesContent":["import { z } from \"zod\"\n\n\nexport const Route = \"/api/rb/auth/me\"\n\nexport const requestSchema = z.object({})\nexport type RequestPayload = z.infer<typeof requestSchema>\n\nexport const responseSchema = z.object({\n id: z.string().optional(),\n email: z.string().email().optional(),\n phone: z.string().optional(),\n name: z.string().optional(),\n tenants: z.array(z.string()).default([]),\n currentTenantId: z.string().optional(),\n signedInTenants: z.array(z.string()).default([]).optional(),\n error: z.string().optional(),\n})\n\nexport type ResponsePayload = z.infer<typeof responseSchema>\n","import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\n\nimport type { AuthSessionUser } from \"../../types\"\nimport { restrictSessionMiddleware } from \"../../middleware\"\n\nimport * as Me from \"./index\"\n\n\nconst me: ApiHandler<Me.RequestPayload, Me.ResponsePayload, AuthSessionUser> = async(\n _payload: Me.RequestPayload,\n ctx: Ctx<AuthSessionUser>\n): Promise<Me.ResponsePayload> => {\n const sessionUser = ctx.req.session?.user\n\n if (!sessionUser?.id) {\n ctx.res.status(401)\n return {\n id: \"\",\n currentTenantId: \"\",\n signedInTenants: [],\n tenants: [],\n error: \"not_authenticated\",\n } as unknown as Me.ResponsePayload\n }\n\n const User = await models.getGlobal(\"RBUser\", ctx)\n const user = await User.findById(sessionUser.id)\n\n if (!user) {\n ctx.res.status(404)\n return {\n id: \"\",\n currentTenantId: \"\",\n signedInTenants: [],\n tenants: [],\n error: \"user_not_found\",\n } as unknown as Me.ResponsePayload\n }\n\n const tenantId = sessionUser.currentTenantId || user.tenants?.[0]?.toString?.() || \"00000000\"\n\n return {\n id: user._id.toString(),\n email: user.email,\n phone: user.get(\"phone\") as string | undefined,\n name: user.name,\n tenants: (user.tenants || []).map(String),\n currentTenantId: tenantId,\n signedInTenants: sessionUser.signedInTenants || [],\n }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.use(Me.Route, restrictSessionMiddleware)\n api.get(Me.Route, me)\n}\n"],"names":["Route","z","id","string","optional","email","phone","name","tenants","default","currentTenantId","signedInTenants","error","me","_payload","ctx","sessionUser","req","session","user","res","status","User","models","getGlobal","findById","tenantId","toString","_id","get","map","String","api","use","Me","restrictSessionMiddleware"],"mappings":";;;AAGO,MAAMA,QAAQ;AAEQC,OAAS,CAAA,CAAE;AAGVA,OAAS;AAAA,EACrCC,IAAID,OAAEE,EAASC,SAAAA;AAAAA,EACfC,OAAOJ,OAAEE,EAASE,MAAAA,EAAQD,SAAAA;AAAAA,EAC1BE,OAAOL,OAAEE,EAASC,SAAAA;AAAAA,EAClBG,MAAMN,OAAEE,EAASC,SAAAA;AAAAA,EACjBI,SAASP,MAAQA,QAAU,EAAEQ,QAAQ,CAAA,CAAE;AAAA,EACvCC,iBAAiBT,OAAEE,EAASC,SAAAA;AAAAA,EAC5BO,iBAAiBV,MAAQA,OAAEE,CAAQ,EAAEM,QAAQ,CAAA,CAAE,EAAEL,SAAAA;AAAAA,EACjDQ,OAAOX,OAAEE,EAASC,SAAAA;AACpB,CAAC;ACRD,MAAMS,KAAyE,OAC7EC,UACAC,QACgC;AAChC,QAAMC,cAAcD,IAAIE,IAAIC,SAASC;AAErC,MAAI,CAACH,aAAad,IAAI;AACpBa,QAAIK,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MACLnB,IAAI;AAAA,MACJQ,iBAAiB;AAAA,MACjBC,iBAAiB,CAAA;AAAA,MACjBH,SAAS,CAAA;AAAA,MACTI,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,QAAMU,OAAO,MAAMC,OAAOC,UAAU,UAAUT,GAAG;AACjD,QAAMI,OAAO,MAAMG,KAAKG,SAAST,YAAYd,EAAE;AAE/C,MAAI,CAACiB,MAAM;AACTJ,QAAIK,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MACLnB,IAAI;AAAA,MACJQ,iBAAiB;AAAA,MACjBC,iBAAiB,CAAA;AAAA,MACjBH,SAAS,CAAA;AAAA,MACTI,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,QAAMc,WAAWV,YAAYN,mBAAmBS,KAAKX,UAAU,CAAC,GAAGmB,gBAAgB;AAEnF,SAAO;AAAA,IACLzB,IAAIiB,KAAKS,IAAID,SAAAA;AAAAA,IACbtB,OAAOc,KAAKd;AAAAA,IACZC,OAAOa,KAAKU,IAAI,OAAO;AAAA,IACvBtB,MAAMY,KAAKZ;AAAAA,IACXC,UAAUW,KAAKX,WAAW,CAAA,GAAIsB,IAAIC,MAAM;AAAA,IACxCrB,iBAAiBgB;AAAAA,IACjBf,iBAAiBK,YAAYL,mBAAmB,CAAA;AAAA,EAAA;AAEpD;AAEA,MAAA,UAAe,CAACqB,QAA8B;AAC5CA,MAAIC,IAAIC,OAAUC,yBAAyB;AAC3CH,MAAIH,IAAIK,OAAUrB,EAAE;AACtB;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler-DfEsSB4T.js","sources":["../src/api/sign-in/handler.ts"],"sourcesContent":["import { Api, ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\nimport { verifyPasswordFromStorage } from \"@rpcbase/server\"\n\nimport type { AuthSessionUser } from \"../../types\"\n\nimport * as SignIn from \"./index\"\n\n\nconst signIn: ApiHandler<SignIn.RequestPayload, SignIn.ResponsePayload, AuthSessionUser> = async(\n payload,\n ctx: Ctx<AuthSessionUser>\n): Promise<SignIn.ResponsePayload> => {\n const User = await models.getGlobal(\"RBUser\", ctx)\n\n const parsed = SignIn.requestSchema.safeParse(payload)\n\n if (!parsed.success) {\n ctx.res.status(400)\n return { success: false, error: \"invalid_payload\" }\n }\n\n const { email, password } = parsed.data\n\n const user = await User.findOne({ email }, { password: 1, tenants: 1, tenantRoles: 1 })\n\n if (!user?.password) {\n ctx.res.status(401)\n return { success: false, error: \"invalid_credentials\" }\n }\n\n const stored = String(user.password)\n const passwordMatches = await verifyPasswordFromStorage(password, stored)\n\n if (!passwordMatches) {\n if (!stored.startsWith(\"$scrypt$\")) {\n console.warn(\"auth::sign-in invalid stored password format\", user._id.toString())\n }\n ctx.res.status(401)\n return { success: false, error: \"invalid_credentials\" }\n }\n\n const tenantId = user.tenants?.[0]?.toString?.() || \"00000000\"\n const signedInTenants = (user.tenants || []).map(String)\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!ctx.req.session) {\n ctx.res.status(500)\n return { success: false, error: \"session_unavailable\" }\n }\n\n ctx.req.session.user = {\n id: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n isEntryGateAuthorized: true,\n tenantRoles,\n }\n\n return { success: true, userId: user._id.toString(), tenantId }\n}\n\nexport default (api: Api<AuthSessionUser>) => {\n api.post(SignIn.Route, signIn)\n}\n"],"names":["signIn","payload","ctx","User","models","getGlobal","parsed","SignIn","safeParse","success","res","status","error","email","password","data","user","findOne","tenants","tenantRoles","stored","String","passwordMatches","verifyPasswordFromStorage","startsWith","console","warn","_id","toString","tenantId","signedInTenants","map","tenantRolesMap","get","Object","fromEntries","entries","undefined","req","session","id","currentTenantId","length","isEntryGateAuthorized","userId","api","post"],"mappings":";;;AASA,MAAMA,SAAqF,OACzFC,SACAC,QACoC;AACpC,QAAMC,OAAO,MAAMC,OAAOC,UAAU,UAAUH,GAAG;AAEjD,QAAMI,SAASC,cAAqBC,UAAUP,OAAO;AAErD,MAAI,CAACK,OAAOG,SAAS;AACnBP,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAM;AAAA,IAAEC;AAAAA,IAAOC;AAAAA,EAAAA,IAAaR,OAAOS;AAEnC,QAAMC,OAAO,MAAMb,KAAKc,QAAQ;AAAA,IAAEJ;AAAAA,EAAAA,GAAS;AAAA,IAAEC,UAAU;AAAA,IAAGI,SAAS;AAAA,IAAGC,aAAa;AAAA,EAAA,CAAG;AAEtF,MAAI,CAACH,MAAMF,UAAU;AACnBZ,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMQ,SAASC,OAAOL,KAAKF,QAAQ;AACnC,QAAMQ,kBAAkB,MAAMC,0BAA0BT,UAAUM,MAAM;AAExE,MAAI,CAACE,iBAAiB;AACpB,QAAI,CAACF,OAAOI,WAAW,UAAU,GAAG;AAClCC,cAAQC,KAAK,gDAAgDV,KAAKW,IAAIC,UAAU;AAAA,IAClF;AACA1B,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEA,QAAMiB,WAAWb,KAAKE,UAAU,CAAC,GAAGU,gBAAgB;AACpD,QAAME,mBAAmBd,KAAKE,WAAW,CAAA,GAAIa,IAAIV,MAAM;AACvD,QAAMW,iBAAiBhB,KAAKiB,IAAI,aAAa;AAC7C,QAAMd,cAAca,iBAAiBE,OAAOC,YAAYH,eAAeI,QAAAA,CAAS,IAAIC;AAEpF,MAAI,CAACnC,IAAIoC,IAAIC,SAAS;AACpBrC,QAAIQ,IAAIC,OAAO,GAAG;AAClB,WAAO;AAAA,MAAEF,SAAS;AAAA,MAAOG,OAAO;AAAA,IAAA;AAAA,EAClC;AAEAV,MAAIoC,IAAIC,QAAQvB,OAAO;AAAA,IACrBwB,IAAIxB,KAAKW,IAAIC,SAAAA;AAAAA,IACba,iBAAiBZ;AAAAA,IACjBC,iBAAiBA,gBAAgBY,SAASZ,kBAAkB,CAACD,QAAQ;AAAA,IACrEc,uBAAuB;AAAA,IACvBxB;AAAAA,EAAAA;AAGF,SAAO;AAAA,IAAEV,SAAS;AAAA,IAAMmC,QAAQ5B,KAAKW,IAAIC,SAAAA;AAAAA,IAAYC;AAAAA,EAAAA;AACvD;AAEA,MAAA,UAAe,CAACgB,QAA8B;AAC5CA,MAAIC,KAAKvC,OAAcP,MAAM;AAC/B;"}