@seamless-auth/core 0.10.0 → 0.12.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.
Files changed (129) hide show
  1. package/README.md +50 -6
  2. package/dist/apiContract.d.ts +41 -0
  3. package/dist/apiContract.d.ts.map +1 -0
  4. package/dist/apiContract.js +48 -0
  5. package/dist/apiContract.js.map +1 -0
  6. package/dist/applyResult.d.ts +100 -0
  7. package/dist/applyResult.d.ts.map +1 -0
  8. package/dist/applyResult.js +95 -0
  9. package/dist/applyResult.js.map +1 -0
  10. package/dist/authMessaging.d.ts +14 -52
  11. package/dist/authMessaging.d.ts.map +1 -1
  12. package/dist/deliverAuthMessage.d.ts +15 -0
  13. package/dist/deliverAuthMessage.d.ts.map +1 -0
  14. package/dist/deliverAuthMessage.js +123 -0
  15. package/dist/deliverAuthMessage.js.map +1 -0
  16. package/dist/ensureCookies.d.ts +2 -2
  17. package/dist/ensureCookies.d.ts.map +1 -1
  18. package/dist/ensureCookies.js +5 -5
  19. package/dist/ensureCookies.js.map +1 -1
  20. package/dist/getSeamlessUser.d.ts +9 -8
  21. package/dist/getSeamlessUser.d.ts.map +1 -1
  22. package/dist/getSeamlessUser.js.map +1 -1
  23. package/dist/guards.d.ts +73 -0
  24. package/dist/guards.d.ts.map +1 -0
  25. package/dist/guards.js +115 -0
  26. package/dist/guards.js.map +1 -0
  27. package/dist/handlers/admin.d.ts +4 -3
  28. package/dist/handlers/admin.d.ts.map +1 -1
  29. package/dist/handlers/admin.js +4 -10
  30. package/dist/handlers/admin.js.map +1 -1
  31. package/dist/handlers/finishLogin.d.ts +2 -2
  32. package/dist/handlers/finishLogin.d.ts.map +1 -1
  33. package/dist/handlers/finishLogin.js +10 -37
  34. package/dist/handlers/finishLogin.js.map +1 -1
  35. package/dist/handlers/finishRegister.d.ts +2 -2
  36. package/dist/handlers/finishRegister.d.ts.map +1 -1
  37. package/dist/handlers/finishRegister.js +10 -34
  38. package/dist/handlers/finishRegister.js.map +1 -1
  39. package/dist/handlers/internalMetrics.d.ts +4 -3
  40. package/dist/handlers/internalMetrics.d.ts.map +1 -1
  41. package/dist/handlers/internalMetrics.js +4 -10
  42. package/dist/handlers/internalMetrics.js.map +1 -1
  43. package/dist/handlers/login.d.ts +2 -2
  44. package/dist/handlers/login.d.ts.map +1 -1
  45. package/dist/handlers/login.js +6 -9
  46. package/dist/handlers/login.js.map +1 -1
  47. package/dist/handlers/logout.d.ts.map +1 -1
  48. package/dist/handlers/logout.js.map +1 -1
  49. package/dist/handlers/me.d.ts +2 -2
  50. package/dist/handlers/me.d.ts.map +1 -1
  51. package/dist/handlers/me.js +1 -1
  52. package/dist/handlers/me.js.map +1 -1
  53. package/dist/handlers/oauthHandlers.d.ts +10 -6
  54. package/dist/handlers/oauthHandlers.d.ts.map +1 -1
  55. package/dist/handlers/oauthHandlers.js +12 -39
  56. package/dist/handlers/oauthHandlers.js.map +1 -1
  57. package/dist/handlers/pollMagicLinkConfirmationHandler.d.ts +2 -2
  58. package/dist/handlers/pollMagicLinkConfirmationHandler.d.ts.map +1 -1
  59. package/dist/handlers/pollMagicLinkConfirmationHandler.js +10 -37
  60. package/dist/handlers/pollMagicLinkConfirmationHandler.js.map +1 -1
  61. package/dist/handlers/register.d.ts +2 -2
  62. package/dist/handlers/register.d.ts.map +1 -1
  63. package/dist/handlers/register.js +4 -4
  64. package/dist/handlers/register.js.map +1 -1
  65. package/dist/handlers/requestMagicLinkHandler.d.ts +2 -2
  66. package/dist/handlers/requestMagicLinkHandler.d.ts.map +1 -1
  67. package/dist/handlers/requestMagicLinkHandler.js +4 -4
  68. package/dist/handlers/requestMagicLinkHandler.js.map +1 -1
  69. package/dist/handlers/requestOtpHandler.d.ts +2 -2
  70. package/dist/handlers/requestOtpHandler.d.ts.map +1 -1
  71. package/dist/handlers/requestOtpHandler.js +4 -4
  72. package/dist/handlers/requestOtpHandler.js.map +1 -1
  73. package/dist/handlers/sessions.d.ts +2 -2
  74. package/dist/handlers/sessions.d.ts.map +1 -1
  75. package/dist/handlers/sessions.js +2 -1
  76. package/dist/handlers/sessions.js.map +1 -1
  77. package/dist/handlers/switchOrganizationHandler.d.ts +2 -2
  78. package/dist/handlers/switchOrganizationHandler.d.ts.map +1 -1
  79. package/dist/handlers/switchOrganizationHandler.js +9 -28
  80. package/dist/handlers/switchOrganizationHandler.js.map +1 -1
  81. package/dist/handlers/systemConfig.d.ts +11 -2
  82. package/dist/handlers/systemConfig.d.ts.map +1 -1
  83. package/dist/handlers/systemConfig.js +29 -3
  84. package/dist/handlers/systemConfig.js.map +1 -1
  85. package/dist/handlers/verifyLoginOtpHandler.d.ts +2 -2
  86. package/dist/handlers/verifyLoginOtpHandler.d.ts.map +1 -1
  87. package/dist/handlers/verifyLoginOtpHandler.js +10 -37
  88. package/dist/handlers/verifyLoginOtpHandler.js.map +1 -1
  89. package/dist/handlers/verifyMagicLinkHandler.d.ts +2 -2
  90. package/dist/handlers/verifyMagicLinkHandler.d.ts.map +1 -1
  91. package/dist/handlers/verifyMagicLinkHandler.js +2 -1
  92. package/dist/handlers/verifyMagicLinkHandler.js.map +1 -1
  93. package/dist/index.d.ts +15 -1
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +19 -1
  96. package/dist/index.js.map +1 -1
  97. package/dist/logger.d.ts +26 -0
  98. package/dist/logger.d.ts.map +1 -0
  99. package/dist/logger.js +24 -0
  100. package/dist/logger.js.map +1 -0
  101. package/dist/proxyRequest.d.ts +62 -0
  102. package/dist/proxyRequest.d.ts.map +1 -0
  103. package/dist/proxyRequest.js +82 -0
  104. package/dist/proxyRequest.js.map +1 -0
  105. package/dist/redaction.d.ts.map +1 -1
  106. package/dist/redaction.js +8 -2
  107. package/dist/redaction.js.map +1 -1
  108. package/dist/refreshAccessToken.d.ts.map +1 -1
  109. package/dist/refreshAccessToken.js.map +1 -1
  110. package/dist/result.d.ts +23 -0
  111. package/dist/result.d.ts.map +1 -0
  112. package/dist/result.js +2 -0
  113. package/dist/result.js.map +1 -0
  114. package/dist/upstreamError.d.ts +31 -0
  115. package/dist/upstreamError.d.ts.map +1 -0
  116. package/dist/upstreamError.js +49 -0
  117. package/dist/upstreamError.js.map +1 -0
  118. package/dist/upstreamSession.d.ts +53 -0
  119. package/dist/upstreamSession.d.ts.map +1 -0
  120. package/dist/upstreamSession.js +56 -0
  121. package/dist/upstreamSession.js.map +1 -0
  122. package/dist/verifySignedAuthResponse.d.ts.map +1 -1
  123. package/dist/verifySignedAuthResponse.js +2 -1
  124. package/dist/verifySignedAuthResponse.js.map +1 -1
  125. package/package.json +2 -1
  126. package/dist/scopedRoles.d.ts +0 -3
  127. package/dist/scopedRoles.d.ts.map +0 -1
  128. package/dist/scopedRoles.js +0 -39
  129. package/dist/scopedRoles.js.map +0 -1
@@ -0,0 +1,82 @@
1
+ import { authFetch } from "./authFetch.js";
2
+ function isScalar(value) {
3
+ return (typeof value === "string" ||
4
+ typeof value === "number" ||
5
+ typeof value === "boolean");
6
+ }
7
+ /**
8
+ * Builds a querystring for an upstream call.
9
+ *
10
+ * An array becomes repeated parameters (`?type=login&type=logout`), which is
11
+ * what the auth API's schemas accept. Joining them into one comma-separated
12
+ * value produces a parameter that matches nothing upstream.
13
+ */
14
+ export function buildQueryString(query) {
15
+ if (!query)
16
+ return "";
17
+ const params = new URLSearchParams();
18
+ for (const [key, value] of Object.entries(query)) {
19
+ if (Array.isArray(value)) {
20
+ for (const item of value) {
21
+ if (isScalar(item))
22
+ params.append(key, String(item));
23
+ }
24
+ continue;
25
+ }
26
+ if (isScalar(value))
27
+ params.append(key, String(value));
28
+ }
29
+ return params.toString();
30
+ }
31
+ export function buildUpstreamUrl(authServerUrl, path, query) {
32
+ const base = `${authServerUrl}${path.startsWith("/") ? "" : "/"}${path}`;
33
+ const qs = buildQueryString(query);
34
+ return qs ? `${base}?${qs}` : base;
35
+ }
36
+ /**
37
+ * Checks that a request carries the session a proxied route requires.
38
+ *
39
+ * Returns the rejection to send, or `undefined` when the request may proceed.
40
+ * The cookie payload alone is not enough: it survives a refresh, so the route
41
+ * also has to see the specific cookie for the identity it needs.
42
+ */
43
+ export function checkProxyIdentity(input) {
44
+ if (!input.subject) {
45
+ return {
46
+ status: 401,
47
+ errorCode: "Unauthenticated request",
48
+ warn: "Missing expected cookie payload/sub.",
49
+ };
50
+ }
51
+ const required = {
52
+ access: { name: input.accessCookieName, error: "access session required" },
53
+ preAuth: {
54
+ name: input.preAuthCookieName,
55
+ error: "pre-auth session required",
56
+ },
57
+ register: {
58
+ name: input.registrationCookieName,
59
+ error: "registration session required",
60
+ },
61
+ };
62
+ const { name, error } = required[input.identity];
63
+ return input.cookies[name] ? undefined : { status: 401, errorCode: error };
64
+ }
65
+ /**
66
+ * Forwards a request to the auth API and returns its status and body unchanged.
67
+ *
68
+ * Transparent on purpose: a proxied route has no view into what the response
69
+ * means, so a failure body is returned as-is rather than reshaped into a code.
70
+ */
71
+ export async function proxyRequest(opts) {
72
+ const method = opts.method ?? "POST";
73
+ const upstream = await authFetch(buildUpstreamUrl(opts.authServerUrl, opts.path, opts.query), {
74
+ method,
75
+ authorization: opts.authorization,
76
+ serviceAuthorization: opts.serviceAuthorization,
77
+ forwardedClientIp: opts.forwardedClientIp,
78
+ ...(method === "GET" ? {} : { body: opts.body }),
79
+ });
80
+ return { status: upstream.status, body: await upstream.json() };
81
+ }
82
+ //# sourceMappingURL=proxyRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxyRequest.js","sourceRoot":"","sources":["../src/proxyRequest.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAWA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,UAKhD"}
1
+ {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAiBA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,UAKhD"}
package/dist/redaction.js CHANGED
@@ -3,8 +3,14 @@ const SENSITIVE_TEXT_PATTERNS = [
3
3
  [/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, REDACTED],
4
4
  [/\b(Bearer\s+)[A-Za-z0-9._~+/=-]+/gi, `$1${REDACTED}`],
5
5
  [/(\/magic-link\/verify\/)[^/?#\s]+/gi, `$1${REDACTED}`],
6
- [/([?&](?:token|bootstrapToken|state|code|salt)=)[^&#\s]+/gi, `$1${REDACTED}`],
7
- [/\b((?:token|bootstrapToken|verificationToken|identifier|phone|state|code|secret|salt)\s*[:=]\s*)[^,&\s}]+/gi, `$1${REDACTED}`],
6
+ [
7
+ /([?&](?:token|bootstrapToken|state|code|salt)=)[^&#\s]+/gi,
8
+ `$1${REDACTED}`,
9
+ ],
10
+ [
11
+ /\b((?:token|bootstrapToken|verificationToken|identifier|phone|state|code|secret|salt)\s*[:=]\s*)[^,&\s}]+/gi,
12
+ `$1${REDACTED}`,
13
+ ],
8
14
  [/\b(client_secret=)[^&\s]+/gi, `$1${REDACTED}`],
9
15
  ];
10
16
  export function redactSensitiveText(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,MAAM,uBAAuB,GAA4B;IACvD,CAAC,6CAA6C,EAAE,QAAQ,CAAC;IACzD,CAAC,oCAAoC,EAAE,KAAK,QAAQ,EAAE,CAAC;IACvD,CAAC,qCAAqC,EAAE,KAAK,QAAQ,EAAE,CAAC;IACxD,CAAC,2DAA2D,EAAE,KAAK,QAAQ,EAAE,CAAC;IAC9E,CAAC,6GAA6G,EAAE,KAAK,QAAQ,EAAE,CAAC;IAChI,CAAC,6BAA6B,EAAE,KAAK,QAAQ,EAAE,CAAC;CACjD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,OAAO,uBAAuB,CAAC,MAAM,CACnC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,EAC1E,KAAK,CACN,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,MAAM,uBAAuB,GAA4B;IACvD,CAAC,6CAA6C,EAAE,QAAQ,CAAC;IACzD,CAAC,oCAAoC,EAAE,KAAK,QAAQ,EAAE,CAAC;IACvD,CAAC,qCAAqC,EAAE,KAAK,QAAQ,EAAE,CAAC;IACxD;QACE,2DAA2D;QAC3D,KAAK,QAAQ,EAAE;KAChB;IACD;QACE,6GAA6G;QAC7G,KAAK,QAAQ,EAAE;KAChB;IACD,CAAC,6BAA6B,EAAE,KAAK,QAAQ,EAAE,CAAC;CACjD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,OAAO,uBAAuB,CAAC,MAAM,CACnC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,EAC1E,KAAK,CACN,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"refreshAccessToken.d.ts","sourceRoot":"","sources":["../src/refreshAccessToken.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,KAAK,wBAAwB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA+BF,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAyD1C"}
1
+ {"version":3,"file":"refreshAccessToken.d.ts","sourceRoot":"","sources":["../src/refreshAccessToken.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,KAAK,wBAAwB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAkCF,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAyD1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"refreshAccessToken.js","sourceRoot":"","sources":["../src/refreshAccessToken.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"refreshAccessToken.js","sourceRoot":"","sources":["../src/refreshAccessToken.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * How a handler reports a failure.
3
+ *
4
+ * At most one of the two is set, and they are rendered differently, which is
5
+ * why they are separate fields rather than one `error`:
6
+ *
7
+ * - `errorCode` is a code this package chose. The adapter renders it as
8
+ * `{ error, details }`.
9
+ * - `errorBody` is the auth API's own failure body, which the adapter forwards
10
+ * unchanged. Callers read fields off it directly, so it must not be reshaped:
11
+ * the React SDK reads a top-level `code` to tell OAuth failures apart, and a
12
+ * top-level `error` or `message` for the message it shows.
13
+ *
14
+ * Before this split both meanings shared one `error` field, so its type could
15
+ * not be honest about either and an adapter could not render it without knowing
16
+ * which handler produced it.
17
+ */
18
+ export interface ResultFailure {
19
+ errorCode?: string;
20
+ errorBody?: unknown;
21
+ details?: unknown;
22
+ }
23
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
package/dist/result.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import type { ResultFailure } from "./result.js";
2
+ /**
3
+ * Last-resort code for a failure the auth API sent with no body at all.
4
+ *
5
+ * A passthrough route has nothing else to say: it does not interpret the
6
+ * response, so when there is no body there is no detail to forward.
7
+ */
8
+ export declare const UPSTREAM_ERROR_CODE = "upstream_error";
9
+ /**
10
+ * Reads an upstream failure for a route that forwards the auth API's response
11
+ * rather than interpreting it.
12
+ *
13
+ * The body goes through verbatim whenever there is one, because callers read
14
+ * fields off it directly and reshaping it breaks them. An empty body has nothing
15
+ * to forward, and returning it as-is produced a bare status with no body, which
16
+ * left the caller with nothing to act on and the SDK falling back to a generic
17
+ * message (#125). That case becomes a code instead.
18
+ */
19
+ export declare function readPassthroughFailure(data: unknown, fallback?: string): ResultFailure;
20
+ /**
21
+ * Reads an upstream error body into the `{ error, details }` pair the proxy
22
+ * handlers return.
23
+ *
24
+ * The auth API answers a validation failure with a Zod body shaped
25
+ * `{ name, message }` and no `error` key, so keying only off `error` collapsed
26
+ * every one of them to the caller-opaque fallback code and dropped the name of
27
+ * the rejected field (#115). `details` carries the upstream body whenever it
28
+ * holds more than the derived error string.
29
+ */
30
+ export declare function readUpstreamFailure(data: unknown, fallback: string): ResultFailure;
31
+ //# sourceMappingURL=upstreamError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstreamError.d.ts","sourceRoot":"","sources":["../src/upstreamError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,QAAQ,GAAE,MAA4B,GACrC,aAAa,CAEf;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,GACf,aAAa,CAkBf"}
@@ -0,0 +1,49 @@
1
+ function isObject(value) {
2
+ return typeof value === "object" && value !== null;
3
+ }
4
+ /**
5
+ * Last-resort code for a failure the auth API sent with no body at all.
6
+ *
7
+ * A passthrough route has nothing else to say: it does not interpret the
8
+ * response, so when there is no body there is no detail to forward.
9
+ */
10
+ export const UPSTREAM_ERROR_CODE = "upstream_error";
11
+ /**
12
+ * Reads an upstream failure for a route that forwards the auth API's response
13
+ * rather than interpreting it.
14
+ *
15
+ * The body goes through verbatim whenever there is one, because callers read
16
+ * fields off it directly and reshaping it breaks them. An empty body has nothing
17
+ * to forward, and returning it as-is produced a bare status with no body, which
18
+ * left the caller with nothing to act on and the SDK falling back to a generic
19
+ * message (#125). That case becomes a code instead.
20
+ */
21
+ export function readPassthroughFailure(data, fallback = UPSTREAM_ERROR_CODE) {
22
+ return isObject(data) ? { errorBody: data } : { errorCode: fallback };
23
+ }
24
+ /**
25
+ * Reads an upstream error body into the `{ error, details }` pair the proxy
26
+ * handlers return.
27
+ *
28
+ * The auth API answers a validation failure with a Zod body shaped
29
+ * `{ name, message }` and no `error` key, so keying only off `error` collapsed
30
+ * every one of them to the caller-opaque fallback code and dropped the name of
31
+ * the rejected field (#115). `details` carries the upstream body whenever it
32
+ * holds more than the derived error string.
33
+ */
34
+ export function readUpstreamFailure(data, fallback) {
35
+ if (!isObject(data)) {
36
+ return { errorCode: fallback };
37
+ }
38
+ const errorCode = typeof data.error === "string"
39
+ ? data.error
40
+ : typeof data.message === "string"
41
+ ? data.message
42
+ : fallback;
43
+ const keys = Object.keys(data);
44
+ if (keys.length === 1 && data[keys[0]] === errorCode) {
45
+ return { errorCode };
46
+ }
47
+ return { errorCode, details: data };
48
+ }
49
+ //# sourceMappingURL=upstreamError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstreamError.js","sourceRoot":"","sources":["../src/upstreamError.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAa,EACb,WAAmB,mBAAmB;IAEtC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AACxE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAa,EACb,QAAgB;IAEhB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,SAAS,GACb,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;QAC5B,CAAC,CAAC,IAAI,CAAC,KAAK;QACZ,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ;YAChC,CAAC,CAAC,IAAI,CAAC,OAAO;YACd,CAAC,CAAC,QAAQ,CAAC;IAEjB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACrD,OAAO,EAAE,SAAS,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { SessionCookie } from "./applyResult.js";
2
+ /**
3
+ * What the auth API returns when it issues a session.
4
+ *
5
+ * The handlers read these fields off the parsed response, which was untyped
6
+ * before: a rename upstream showed up as an undefined cookie field at runtime
7
+ * rather than a type error here.
8
+ *
9
+ * The index signature is deliberate. Several handlers forward the whole body to
10
+ * the caller, so it carries more than the fields this package reads, and the
11
+ * type should not claim otherwise.
12
+ */
13
+ export interface UpstreamSessionResponse {
14
+ sub: string;
15
+ token: string;
16
+ refreshToken?: string;
17
+ roles?: string[];
18
+ email?: string;
19
+ phone?: string | null;
20
+ organizationId?: string | null;
21
+ ttl: number;
22
+ refreshTtl?: number;
23
+ [key: string]: unknown;
24
+ }
25
+ export interface VerifiedUpstreamSession {
26
+ /** The `sid` claim, when the access token carries one. */
27
+ sessionId?: string;
28
+ }
29
+ /**
30
+ * Verifies the access token the auth API signed and confirms it describes the
31
+ * same subject as the response body.
32
+ *
33
+ * Throws rather than returning a failure: a response that fails either check is
34
+ * not a rejected login, it is a response this package cannot trust, and
35
+ * continuing would mint a session from it.
36
+ */
37
+ export declare function verifyUpstreamSession(data: UpstreamSessionResponse, authServerUrl: string, audience: string): Promise<VerifiedUpstreamSession>;
38
+ export interface IssueSessionCookiesOptions {
39
+ authServerUrl: string;
40
+ audience: string;
41
+ accessCookieName: string;
42
+ /** Omit for a flow that reissues the access cookie without rotating refresh. */
43
+ refreshCookieName?: string;
44
+ cookieDomain?: string;
45
+ }
46
+ /**
47
+ * Verifies an upstream session response and builds the cookies for it.
48
+ *
49
+ * One place decides what a session cookie holds, so the flows that issue one
50
+ * cannot disagree about it.
51
+ */
52
+ export declare function issueSessionCookies(data: UpstreamSessionResponse, opts: IssueSessionCookiesOptions): Promise<SessionCookie[]>;
53
+ //# sourceMappingURL=upstreamSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstreamSession.d.ts","sourceRoot":"","sources":["../src/upstreamSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,uBAAuB,EAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,uBAAuB,CAAC,CAkBlC;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,uBAAuB,EAC7B,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,aAAa,EAAE,CAAC,CAkC1B"}
@@ -0,0 +1,56 @@
1
+ import { verifySignedAuthResponse } from "./verifySignedAuthResponse.js";
2
+ /**
3
+ * Verifies the access token the auth API signed and confirms it describes the
4
+ * same subject as the response body.
5
+ *
6
+ * Throws rather than returning a failure: a response that fails either check is
7
+ * not a rejected login, it is a response this package cannot trust, and
8
+ * continuing would mint a session from it.
9
+ */
10
+ export async function verifyUpstreamSession(data, authServerUrl, audience) {
11
+ const verified = await verifySignedAuthResponse(data.token, authServerUrl, audience);
12
+ if (!verified) {
13
+ throw new Error("Invalid signed response from Auth Server");
14
+ }
15
+ if (verified.sub !== data.sub) {
16
+ throw new Error("Signature mismatch with data payload");
17
+ }
18
+ return {
19
+ sessionId: typeof verified.sid === "string" ? verified.sid : undefined,
20
+ };
21
+ }
22
+ /**
23
+ * Verifies an upstream session response and builds the cookies for it.
24
+ *
25
+ * One place decides what a session cookie holds, so the flows that issue one
26
+ * cannot disagree about it.
27
+ */
28
+ export async function issueSessionCookies(data, opts) {
29
+ const { sessionId } = await verifyUpstreamSession(data, opts.authServerUrl, opts.audience);
30
+ const cookies = [
31
+ {
32
+ name: opts.accessCookieName,
33
+ value: {
34
+ sub: data.sub,
35
+ ...(sessionId === undefined ? {} : { sessionId }),
36
+ token: data.token,
37
+ roles: data.roles,
38
+ email: data.email,
39
+ phone: data.phone,
40
+ organizationId: data.organizationId ?? null,
41
+ },
42
+ ttl: data.ttl,
43
+ domain: opts.cookieDomain,
44
+ },
45
+ ];
46
+ if (opts.refreshCookieName) {
47
+ cookies.push({
48
+ name: opts.refreshCookieName,
49
+ value: { sub: data.sub, refreshToken: data.refreshToken },
50
+ ttl: data.refreshTtl,
51
+ domain: opts.cookieDomain,
52
+ });
53
+ }
54
+ return cookies;
55
+ }
56
+ //# sourceMappingURL=upstreamSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstreamSession.js","sourceRoot":"","sources":["../src/upstreamSession.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AA+BzE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA6B,EAC7B,aAAqB,EACrB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC7C,IAAI,CAAC,KAAK,EACV,aAAa,EACb,QAAQ,CACT,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,SAAS,EAAE,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;KACvE,CAAC;AACJ,CAAC;AAWD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAA6B,EAC7B,IAAgC;IAEhC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,qBAAqB,CAC/C,IAAI,EACJ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,QAAQ,CACd,CAAC;IAEF,MAAM,OAAO,GAAoB;QAC/B;YACE,IAAI,EAAE,IAAI,CAAC,gBAAgB;YAC3B,KAAK,EAAE;gBACL,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;gBACjD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;aAC5C;YACD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,MAAM,EAAE,IAAI,CAAC,YAAY;SAC1B;KACF,CAAC;IAEF,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,iBAAiB;YAC5B,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;YACzD,GAAG,EAAE,IAAI,CAAC,UAAoB;YAC9B,MAAM,EAAE,IAAI,CAAC,YAAY;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"verifySignedAuthResponse.d.ts","sourceRoot":"","sources":["../src/verifySignedAuthResponse.ts"],"names":[],"mappings":"AAgBA,wBAAsB,wBAAwB,CAAC,CAAC,GAAG,GAAG,EACpD,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAgBnB"}
1
+ {"version":3,"file":"verifySignedAuthResponse.d.ts","sourceRoot":"","sources":["../src/verifySignedAuthResponse.ts"],"names":[],"mappings":"AAiBA,wBAAsB,wBAAwB,CAAC,CAAC,GAAG,GAAG,EACpD,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAkBnB"}
@@ -1,4 +1,5 @@
1
1
  import { createRemoteJWKSet, jwtVerify } from "jose";
2
+ import { getSeamlessLogger } from "./logger.js";
2
3
  // jose caches keys and applies a refetch cooldown per JWKS instance, so the instance
3
4
  // must outlive a single call. Memoize per JWKS URL (one per auth server, so the map
4
5
  // stays tiny) instead of building a fresh, empty-cache instance on every verification.
@@ -23,7 +24,7 @@ export async function verifySignedAuthResponse(token, authServerUrl, audience) {
23
24
  return payload;
24
25
  }
25
26
  catch {
26
- console.error("[SeamlessAuth] Failed to verify signed auth response.");
27
+ getSeamlessLogger().error("[SeamlessAuth] Failed to verify signed auth response.");
27
28
  return null;
28
29
  }
29
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"verifySignedAuthResponse.js","sourceRoot":"","sources":["../src/verifySignedAuthResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAErD,qFAAqF;AACrF,oFAAoF;AACpF,uFAAuF;AACvF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;AAE3E,SAAS,OAAO,CAAC,OAAe;IAC9B,IAAI,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAa,EACb,aAAqB,EACrB,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAE9B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/C,UAAU,EAAE,CAAC,OAAO,CAAC;YACrB,MAAM,EAAE,aAAa;YACrB,QAAQ;SACT,CAAC,CAAC;QAEH,OAAO,OAAY,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"verifySignedAuthResponse.js","sourceRoot":"","sources":["../src/verifySignedAuthResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,qFAAqF;AACrF,oFAAoF;AACpF,uFAAuF;AACvF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;AAE3E,SAAS,OAAO,CAAC,OAAe;IAC9B,IAAI,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAa,EACb,aAAqB,EACrB,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAE9B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/C,UAAU,EAAE,CAAC,OAAO,CAAC;YACrB,MAAM,EAAE,aAAa;YACrB,QAAQ;SACT,CAAC,CAAC;QAEH,OAAO,OAAY,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB,EAAE,CAAC,KAAK,CACvB,uDAAuD,CACxD,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamless-auth/core",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Framework-agnostic core authentication logic for SeamlessAuth",
5
5
  "keywords": [
6
6
  "authentication",
@@ -45,6 +45,7 @@
45
45
  "node": ">=24 <25"
46
46
  },
47
47
  "dependencies": {
48
+ "@seamless-auth/types": "^0.4.0",
48
49
  "jose": "^6.1.3",
49
50
  "jsonwebtoken": "^9.0.2"
50
51
  },
@@ -1,3 +0,0 @@
1
- export declare function roleGrantsAccess(grantedRole: string, requiredRole: string): boolean;
2
- export declare function hasScopedRole(grantedRoles: unknown, requiredRoles: string | string[]): boolean;
3
- //# sourceMappingURL=scopedRoles.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scopedRoles.d.ts","sourceRoot":"","sources":["../src/scopedRoles.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAsCnF;AAED,wBAAgB,aAAa,CAC3B,YAAY,EAAE,OAAO,EACrB,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAC/B,OAAO,CAaT"}
@@ -1,39 +0,0 @@
1
- export function roleGrantsAccess(grantedRole, requiredRole) {
2
- const granted = grantedRole.trim();
3
- const required = requiredRole.trim();
4
- if (!granted || !required) {
5
- return false;
6
- }
7
- if (granted === required) {
8
- return true;
9
- }
10
- if (granted.endsWith(":*")) {
11
- const prefix = granted.slice(0, -2);
12
- return required === prefix || required.startsWith(`${prefix}:`);
13
- }
14
- if (!required.includes(":")) {
15
- return false;
16
- }
17
- if (!granted.includes(":")) {
18
- return required.startsWith(`${granted}:`);
19
- }
20
- const grantedParts = granted.split(":");
21
- const requiredParts = required.split(":");
22
- const grantedAction = grantedParts.at(-1);
23
- const requiredAction = requiredParts.at(-1);
24
- const grantedPrefix = grantedParts.slice(0, -1);
25
- const requiredPrefix = requiredParts.slice(0, -1);
26
- return (grantedAction === "write" &&
27
- requiredAction === "read" &&
28
- grantedPrefix.length === requiredPrefix.length &&
29
- grantedPrefix.every((part, index) => part === requiredPrefix[index]));
30
- }
31
- export function hasScopedRole(grantedRoles, requiredRoles) {
32
- if (!Array.isArray(grantedRoles)) {
33
- return false;
34
- }
35
- const granted = grantedRoles.filter((role) => typeof role === "string");
36
- const required = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
37
- return required.some((requiredRole) => granted.some((grantedRole) => roleGrantsAccess(grantedRole, requiredRole)));
38
- }
39
- //# sourceMappingURL=scopedRoles.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scopedRoles.js","sourceRoot":"","sources":["../src/scopedRoles.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,YAAoB;IACxE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IAErC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAElD,OAAO,CACL,aAAa,KAAK,OAAO;QACzB,cAAc,KAAK,MAAM;QACzB,aAAa,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;QAC9C,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,YAAqB,EACrB,aAAgC;IAEhC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CACjC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CACnD,CAAC;IACF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAEhF,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CACpC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC"}