@atlasauth/backend 0.23.0 → 0.25.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 (188) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/auth0-session.d.ts +23 -0
  3. package/dist/auth0-session.js +80 -0
  4. package/dist/auth0-session.js.map +1 -0
  5. package/dist/better-auth.d.ts +4 -8
  6. package/dist/better-auth.js +42 -150
  7. package/dist/better-auth.js.map +1 -1
  8. package/dist/client/abac.d.ts +132 -0
  9. package/dist/client/abac.js +48 -0
  10. package/dist/client/abac.js.map +1 -0
  11. package/dist/client/access-policies.d.ts +100 -0
  12. package/dist/client/access-policies.js +29 -0
  13. package/dist/client/access-policies.js.map +1 -0
  14. package/dist/client/action-gallery.d.ts +1 -1
  15. package/dist/client/action-gallery.js.map +1 -1
  16. package/dist/client/actions.d.ts +129 -6
  17. package/dist/client/actions.js +4 -0
  18. package/dist/client/actions.js.map +1 -1
  19. package/dist/client/analytics-reports.d.ts +215 -0
  20. package/dist/client/analytics-reports.js +56 -0
  21. package/dist/client/analytics-reports.js.map +1 -0
  22. package/dist/client/app-catalog.d.ts +74 -0
  23. package/dist/client/app-catalog.js +30 -0
  24. package/dist/client/app-catalog.js.map +1 -0
  25. package/dist/client/attack-protection.d.ts +10 -0
  26. package/dist/client/attack-protection.js +8 -0
  27. package/dist/client/attack-protection.js.map +1 -1
  28. package/dist/client/audit-events.d.ts +71 -0
  29. package/dist/client/audit-events.js +28 -0
  30. package/dist/client/audit-events.js.map +1 -1
  31. package/dist/client/credentials.d.ts +8 -0
  32. package/dist/client/credentials.js.map +1 -1
  33. package/dist/client/delegated-ui-proxy.d.ts +25 -0
  34. package/dist/client/delegated-ui-proxy.js +46 -0
  35. package/dist/client/delegated-ui-proxy.js.map +1 -0
  36. package/dist/client/devices.d.ts +44 -0
  37. package/dist/client/devices.js +26 -0
  38. package/dist/client/devices.js.map +1 -0
  39. package/dist/client/email-templates.d.ts +1 -1
  40. package/dist/client/email-templates.js.map +1 -1
  41. package/dist/client/flags.d.ts +101 -0
  42. package/dist/client/flags.js +104 -0
  43. package/dist/client/flags.js.map +1 -0
  44. package/dist/client/groups.d.ts +146 -0
  45. package/dist/client/groups.js +67 -0
  46. package/dist/client/groups.js.map +1 -0
  47. package/dist/client/identity-verification.d.ts +62 -0
  48. package/dist/client/identity-verification.js +39 -0
  49. package/dist/client/identity-verification.js.map +1 -0
  50. package/dist/client/index.d.ts +997 -2
  51. package/dist/client/index.js +77 -0
  52. package/dist/client/index.js.map +1 -1
  53. package/dist/client/journeys.d.ts +108 -0
  54. package/dist/client/journeys.js +35 -0
  55. package/dist/client/journeys.js.map +1 -0
  56. package/dist/client/log-streams.d.ts +1 -1
  57. package/dist/client/marketing.d.ts +67 -0
  58. package/dist/client/marketing.js +26 -0
  59. package/dist/client/marketing.js.map +1 -0
  60. package/dist/client/mcp-gateways.d.ts +54 -0
  61. package/dist/client/mcp-gateways.js +25 -0
  62. package/dist/client/mcp-gateways.js.map +1 -0
  63. package/dist/client/messaging.d.ts +14 -3
  64. package/dist/client/messaging.js.map +1 -1
  65. package/dist/client/mfa-factors.d.ts +120 -0
  66. package/dist/client/mfa-factors.js +73 -0
  67. package/dist/client/mfa-factors.js.map +1 -0
  68. package/dist/client/migrations.d.ts +286 -0
  69. package/dist/client/migrations.js +103 -0
  70. package/dist/client/migrations.js.map +1 -0
  71. package/dist/client/network-acls.d.ts +6 -1
  72. package/dist/client/network-acls.js.map +1 -1
  73. package/dist/client/network-zones.d.ts +56 -0
  74. package/dist/client/network-zones.js +29 -0
  75. package/dist/client/network-zones.js.map +1 -0
  76. package/dist/client/notifications.d.ts +1 -1
  77. package/dist/client/notifications.js.map +1 -1
  78. package/dist/client/oauth-clients.d.ts +183 -3
  79. package/dist/client/oauth-clients.js +64 -0
  80. package/dist/client/oauth-clients.js.map +1 -1
  81. package/dist/client/org-role-grants.d.ts +57 -0
  82. package/dist/client/org-role-grants.js +40 -0
  83. package/dist/client/org-role-grants.js.map +1 -0
  84. package/dist/client/organizations.d.ts +52 -0
  85. package/dist/client/organizations.js +44 -0
  86. package/dist/client/organizations.js.map +1 -1
  87. package/dist/client/page-templates.d.ts +78 -0
  88. package/dist/client/page-templates.js +31 -0
  89. package/dist/client/page-templates.js.map +1 -0
  90. package/dist/client/passkey-api.d.ts +73 -0
  91. package/dist/client/passkey-api.js +34 -0
  92. package/dist/client/passkey-api.js.map +1 -0
  93. package/dist/client/resources.d.ts +149 -0
  94. package/dist/client/resources.js +73 -0
  95. package/dist/client/resources.js.map +1 -0
  96. package/dist/client/risk-based-mfa.d.ts +147 -0
  97. package/dist/client/risk-based-mfa.js +30 -0
  98. package/dist/client/risk-based-mfa.js.map +1 -1
  99. package/dist/client/roles.d.ts +4 -0
  100. package/dist/client/roles.js.map +1 -1
  101. package/dist/client/service-connectors.d.ts +83 -0
  102. package/dist/client/service-connectors.js +33 -0
  103. package/dist/client/service-connectors.js.map +1 -0
  104. package/dist/client/ssf.d.ts +111 -0
  105. package/dist/client/ssf.js +49 -0
  106. package/dist/client/ssf.js.map +1 -0
  107. package/dist/client/sso-onboarding.d.ts +6 -0
  108. package/dist/client/sso-onboarding.js.map +1 -1
  109. package/dist/client/users.d.ts +302 -0
  110. package/dist/client/users.js +125 -0
  111. package/dist/client/users.js.map +1 -1
  112. package/dist/client/vault.d.ts +85 -0
  113. package/dist/client/vault.js +50 -0
  114. package/dist/client/vault.js.map +1 -0
  115. package/dist/client/vc.d.ts +128 -0
  116. package/dist/client/vc.js +43 -0
  117. package/dist/client/vc.js.map +1 -0
  118. package/dist/client/webhooks.d.ts +31 -2
  119. package/dist/client/webhooks.js.map +1 -1
  120. package/dist/client/workflows.d.ts +131 -0
  121. package/dist/client/workflows.js +36 -0
  122. package/dist/client/workflows.js.map +1 -0
  123. package/dist/framework-bridge.d.ts +98 -0
  124. package/dist/framework-bridge.js +264 -0
  125. package/dist/framework-bridge.js.map +1 -0
  126. package/dist/framework-sessions.d.ts +147 -0
  127. package/dist/framework-sessions.js +544 -0
  128. package/dist/framework-sessions.js.map +1 -0
  129. package/dist/index.d.ts +11 -1
  130. package/dist/index.js +19 -2
  131. package/dist/index.js.map +1 -1
  132. package/dist/legacy-issuer-presets.d.ts +85 -0
  133. package/dist/legacy-issuer-presets.js +165 -0
  134. package/dist/legacy-issuer-presets.js.map +1 -0
  135. package/dist/legacy-issuers.d.ts +16 -2
  136. package/dist/legacy-issuers.js +16 -1
  137. package/dist/legacy-issuers.js.map +1 -1
  138. package/dist/legacy-verify.d.ts +103 -0
  139. package/dist/legacy-verify.js +244 -0
  140. package/dist/legacy-verify.js.map +1 -0
  141. package/dist/magic-did.d.ts +5 -0
  142. package/dist/magic-did.js +49 -0
  143. package/dist/magic-did.js.map +1 -0
  144. package/dist/migration-bridge.d.ts +162 -0
  145. package/dist/migration-bridge.js +354 -0
  146. package/dist/migration-bridge.js.map +1 -0
  147. package/dist/migration-presets-g3.d.ts +2 -0
  148. package/dist/migration-presets-g3.js +254 -0
  149. package/dist/migration-presets-g3.js.map +1 -0
  150. package/dist/migration-presets-g4/authentik.d.ts +14 -0
  151. package/dist/migration-presets-g4/authentik.js +37 -0
  152. package/dist/migration-presets-g4/authentik.js.map +1 -0
  153. package/dist/migration-presets-g4/fusionauth.d.ts +2 -0
  154. package/dist/migration-presets-g4/fusionauth.js +52 -0
  155. package/dist/migration-presets-g4/fusionauth.js.map +1 -0
  156. package/dist/migration-presets-g4/hanko.d.ts +12 -0
  157. package/dist/migration-presets-g4/hanko.js +46 -0
  158. package/dist/migration-presets-g4/hanko.js.map +1 -0
  159. package/dist/migration-presets-g4/keycloak.d.ts +16 -0
  160. package/dist/migration-presets-g4/keycloak.js +37 -0
  161. package/dist/migration-presets-g4/keycloak.js.map +1 -0
  162. package/dist/migration-presets-g4/logto.d.ts +12 -0
  163. package/dist/migration-presets-g4/logto.js +35 -0
  164. package/dist/migration-presets-g4/logto.js.map +1 -0
  165. package/dist/migration-presets-g4/ory.d.ts +2 -0
  166. package/dist/migration-presets-g4/ory.js +67 -0
  167. package/dist/migration-presets-g4/ory.js.map +1 -0
  168. package/dist/migration-presets-g4/supertokens.d.ts +13 -0
  169. package/dist/migration-presets-g4/supertokens.js +35 -0
  170. package/dist/migration-presets-g4/supertokens.js.map +1 -0
  171. package/dist/migration-presets-g4/zitadel.d.ts +2 -0
  172. package/dist/migration-presets-g4/zitadel.js +36 -0
  173. package/dist/migration-presets-g4/zitadel.js.map +1 -0
  174. package/dist/migration-presets-g4.d.ts +10 -0
  175. package/dist/migration-presets-g4.js +30 -0
  176. package/dist/migration-presets-g4.js.map +1 -0
  177. package/dist/migration-presets.d.ts +156 -0
  178. package/dist/migration-presets.js +536 -0
  179. package/dist/migration-presets.js.map +1 -0
  180. package/dist/request-auth.d.ts +32 -0
  181. package/dist/request-auth.js +72 -0
  182. package/dist/request-auth.js.map +1 -0
  183. package/dist/verify.d.ts +2 -0
  184. package/dist/verify.js.map +1 -1
  185. package/dist/workos-session.d.ts +30 -0
  186. package/dist/workos-session.js +123 -0
  187. package/dist/workos-session.js.map +1 -0
  188. package/package.json +1 -1
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleLegacyVerify = handleLegacyVerify;
4
+ exports.oktaPasswordVerifier = oktaPasswordVerifier;
5
+ exports.auth0PasswordVerifier = auth0PasswordVerifier;
6
+ exports.descopePasswordVerifier = descopePasswordVerifier;
7
+ exports.clerkPasswordVerifier = clerkPasswordVerifier;
8
+ const jose_1 = require("jose");
9
+ const webhooks_1 = require("./webhooks");
10
+ const DEFAULT_TIMEOUT_MS = 4000;
11
+ /**
12
+ * Check Atlas's signature on the request and run `verify`. Returns the status
13
+ * and JSON body to send: 200 `{ user }` on a valid credential, 401 when the
14
+ * old system rejected it, 400 on a bad signature or body.
15
+ */
16
+ async function handleLegacyVerify(input) {
17
+ const checked = (0, webhooks_1.verifyWebhook)({
18
+ body: input.body,
19
+ headers: input.headers,
20
+ secret: input.secret,
21
+ now: input.now,
22
+ });
23
+ if (!checked.verified)
24
+ return { status: 400, body: { error: 'invalid_signature' } };
25
+ const identifier = typeof checked.event?.identifier === 'string' ? checked.event.identifier.trim() : '';
26
+ const password = typeof checked.event?.password === 'string' ? checked.event.password : '';
27
+ if (!identifier || !password)
28
+ return { status: 400, body: { error: 'invalid_body' } };
29
+ let profile = null;
30
+ try {
31
+ profile = await input.verify({ identifier, password });
32
+ }
33
+ catch {
34
+ profile = null;
35
+ }
36
+ if (!profile || !profile.email.includes('@'))
37
+ return { status: 401, body: { error: 'invalid_credentials' } };
38
+ return { status: 200, body: { user: profile } };
39
+ }
40
+ const str = (v) => (typeof v === 'string' && v.trim() ? v.trim() : undefined);
41
+ const obj = (v) => v && typeof v === 'object' && !Array.isArray(v) ? v : undefined;
42
+ async function call(t, url, init) {
43
+ const controller = new AbortController();
44
+ const timer = setTimeout(() => controller.abort(), t.timeoutMs ?? DEFAULT_TIMEOUT_MS);
45
+ try {
46
+ const res = await (t.fetchImpl ?? fetch)(url, { ...init, signal: controller.signal, redirect: 'manual' });
47
+ let raw = null;
48
+ try {
49
+ raw = (await res.json());
50
+ }
51
+ catch {
52
+ raw = null;
53
+ }
54
+ return { status: res.status, json: obj(raw) ?? null, raw };
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ finally {
60
+ clearTimeout(timer);
61
+ }
62
+ }
63
+ const origin = (domain) => `https://${domain.replace(/^https?:\/\//, '').replace(/\/+$/, '')}`;
64
+ const joinName = (...parts) => parts.filter(Boolean).join(' ').trim() || undefined;
65
+ /**
66
+ * Okta (Workforce Identity Cloud / Customer Identity Solution): the Authn API,
67
+ * `POST /api/v1/authn`, needs no API token. A primary-authentication result of
68
+ * SUCCESS, or any state that is only reached after a correct password
69
+ * (MFA_REQUIRED, MFA_ENROLL, PASSWORD_WARN, PASSWORD_EXPIRED), counts as
70
+ * verified; 401 (E0000004) and LOCKED_OUT do not.
71
+ *
72
+ * Orgs where the Authn API is turned off can verify with the resource-owner
73
+ * password grant of an app that allows it: pass `passwordGrant`.
74
+ */
75
+ function oktaPasswordVerifier(opts) {
76
+ const base = origin(opts.domain);
77
+ const PASSED = new Set(['SUCCESS', 'MFA_REQUIRED', 'MFA_ENROLL', 'MFA_CHALLENGE', 'PASSWORD_WARN', 'PASSWORD_EXPIRED']);
78
+ return async ({ identifier, password }) => {
79
+ if (opts.passwordGrant) {
80
+ const g = opts.passwordGrant;
81
+ const server = g.authorizationServerId ?? 'default';
82
+ const form = new URLSearchParams({ grant_type: 'password', username: identifier, password, scope: 'openid email profile', client_id: g.clientId });
83
+ if (g.clientSecret)
84
+ form.set('client_secret', g.clientSecret);
85
+ const res = await call(opts, `${base}/oauth2/${server}/v1/token`, {
86
+ method: 'POST',
87
+ headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' },
88
+ body: form.toString(),
89
+ });
90
+ if (!res || res.status !== 200)
91
+ return null;
92
+ return profileFromIdToken(str(res.json?.id_token), { externalIdClaim: 'sub' });
93
+ }
94
+ const res = await call(opts, `${base}/api/v1/authn`, {
95
+ method: 'POST',
96
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
97
+ body: JSON.stringify({ username: identifier, password, options: { warnBeforePasswordExpired: false, multiOptionalFactorEnroll: false } }),
98
+ });
99
+ if (!res || res.status !== 200 || !res.json)
100
+ return null;
101
+ if (!PASSED.has(String(res.json.status)))
102
+ return null;
103
+ const user = obj(obj(res.json._embedded)?.user);
104
+ const profile = obj(user?.profile);
105
+ const email = str(profile?.login)?.includes('@') ? str(profile?.login) : undefined;
106
+ if (!email)
107
+ return null;
108
+ return {
109
+ email: email.toLowerCase(),
110
+ // Okta proved the user controls the login; it does not say the address was verified.
111
+ email_verified: false,
112
+ name: joinName(str(profile?.firstName), str(profile?.lastName)),
113
+ external_id: str(user?.id),
114
+ };
115
+ };
116
+ }
117
+ /**
118
+ * Auth0 (and Okta Customer Identity Cloud): the resource-owner password grant
119
+ * against ONE database connection (`realm`), from an application with the
120
+ * Password grant enabled. `mfa_required` means the password was right (Auth0
121
+ * only asks for the second factor after it). Use a dedicated application for
122
+ * this and keep its secret on your server.
123
+ */
124
+ function auth0PasswordVerifier(opts) {
125
+ const base = origin(opts.domain);
126
+ return async ({ identifier, password }) => {
127
+ const body = {
128
+ grant_type: 'http://auth0.com/oauth/grant-type/password-realm',
129
+ realm: opts.realm,
130
+ username: identifier,
131
+ password,
132
+ client_id: opts.clientId,
133
+ scope: 'openid email profile',
134
+ };
135
+ if (opts.clientSecret)
136
+ body.client_secret = opts.clientSecret;
137
+ if (opts.audience)
138
+ body.audience = opts.audience;
139
+ const res = await call(opts, `${base}/oauth/token`, {
140
+ method: 'POST',
141
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
142
+ body: JSON.stringify(body),
143
+ });
144
+ if (!res)
145
+ return null;
146
+ if (res.status === 200)
147
+ return profileFromIdToken(str(res.json?.id_token), { externalIdClaim: 'sub' });
148
+ if (res.status === 403 && res.json?.error === 'mfa_required') {
149
+ // No ID token yet: the password is right, the profile comes from the MFA
150
+ // token's user. Atlas needs at least the email, which is the identifier.
151
+ return identifier.includes('@') ? { email: identifier.toLowerCase(), email_verified: false } : null;
152
+ }
153
+ return null;
154
+ };
155
+ }
156
+ /**
157
+ * Descope: `POST /v1/auth/password/signin` with the project id (public — no
158
+ * management key). A 200 with a `user` means the password is right.
159
+ */
160
+ function descopePasswordVerifier(opts) {
161
+ const base = origin(opts.baseUrl ?? 'api.descope.com');
162
+ return async ({ identifier, password }) => {
163
+ const res = await call(opts, `${base}/v1/auth/password/signin`, {
164
+ method: 'POST',
165
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${opts.projectId}` },
166
+ body: JSON.stringify({ loginId: identifier, password }),
167
+ });
168
+ if (!res || res.status !== 200 || !res.json)
169
+ return null;
170
+ const user = obj(res.json.user);
171
+ const email = str(user?.email) ?? (identifier.includes('@') ? identifier : undefined);
172
+ if (!user || !email)
173
+ return null;
174
+ return {
175
+ email: email.toLowerCase(),
176
+ email_verified: user.verifiedEmail === true,
177
+ name: str(user.name) ?? joinName(str(user.givenName), str(user.familyName)),
178
+ external_id: str(user.userId),
179
+ };
180
+ };
181
+ }
182
+ /**
183
+ * Clerk exports bcrypt digests, so most moves need no lazy step. For users
184
+ * whose digest could not move (a peppered or Cognito-backed hasher), look the
185
+ * user up by email and call `POST /v1/users/{id}/verify_password` with your
186
+ * Clerk secret key.
187
+ */
188
+ function clerkPasswordVerifier(opts) {
189
+ const base = (opts.apiUrl ?? 'https://api.clerk.com').replace(/\/+$/, '');
190
+ const headers = { authorization: `Bearer ${opts.secretKey}`, 'content-type': 'application/json', accept: 'application/json' };
191
+ return async ({ identifier, password }) => {
192
+ if (!identifier.includes('@'))
193
+ return null;
194
+ const found = await call(opts, `${base}/v1/users?email_address=${encodeURIComponent(identifier)}&limit=1`, { headers });
195
+ if (!found || found.status !== 200)
196
+ return null;
197
+ // GET /v1/users answers with a bare array (or `{ data }` from newer API versions).
198
+ const list = Array.isArray(found.raw) ? found.raw : Array.isArray(found.json?.data) ? found.json.data : [];
199
+ const user = obj(list[0]);
200
+ const id = str(user?.id);
201
+ if (!user || !id)
202
+ return null;
203
+ const res = await call(opts, `${base}/v1/users/${encodeURIComponent(id)}/verify_password`, {
204
+ method: 'POST',
205
+ headers,
206
+ body: JSON.stringify({ password }),
207
+ });
208
+ if (!res || res.status !== 200 || res.json?.verified !== true)
209
+ return null;
210
+ const emails = Array.isArray(user.email_addresses) ? user.email_addresses.map(obj) : [];
211
+ const primary = emails.find((e) => e && e.id === user.primary_email_address_id) ?? emails[0];
212
+ return {
213
+ email: (str(primary?.email_address) ?? identifier).toLowerCase(),
214
+ email_verified: obj(primary?.verification)?.status === 'verified',
215
+ name: joinName(str(user.first_name), str(user.last_name)),
216
+ external_id: id,
217
+ };
218
+ };
219
+ }
220
+ /**
221
+ * The profile in an ID token returned DIRECTLY by the vendor's token endpoint
222
+ * over TLS (so its signature need not be re-checked here).
223
+ */
224
+ function profileFromIdToken(idToken, o) {
225
+ if (!idToken)
226
+ return null;
227
+ let claims;
228
+ try {
229
+ claims = (0, jose_1.decodeJwt)(idToken);
230
+ }
231
+ catch {
232
+ return null;
233
+ }
234
+ const email = str(claims.email);
235
+ if (!email || !email.includes('@'))
236
+ return null;
237
+ return {
238
+ email: email.toLowerCase(),
239
+ email_verified: claims.email_verified === true,
240
+ name: str(claims.name) ?? joinName(str(claims.given_name), str(claims.family_name)),
241
+ external_id: str(claims[o.externalIdClaim]),
242
+ };
243
+ }
244
+ //# sourceMappingURL=legacy-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-verify.js","sourceRoot":"","sources":["../src/legacy-verify.ts"],"names":[],"mappings":";;AAmDA,gDAyBC;AA2CD,oDAyCC;AASD,sDA6BC;AAMD,0DAqBC;AAQD,sDA6BC;AAtQD,+BAAiC;AACjC,yCAA2C;AA2C3C,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;;;;GAIG;AACI,KAAK,UAAU,kBAAkB,CAAC,KAMxC;IACC,MAAM,OAAO,GAAG,IAAA,wBAAa,EAA+C;QAC1E,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,EAAE,KAAK,CAAC,GAAG;KACf,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAC;IACpF,MAAM,UAAU,GAAG,OAAO,OAAO,CAAC,KAAK,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxG,MAAM,QAAQ,GAAG,OAAO,OAAO,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3F,IAAI,CAAC,UAAU,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,CAAC;IACtF,IAAI,OAAO,GAAiC,IAAI,CAAC;IACjD,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,CAAC;IAC7G,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC3G,MAAM,GAAG,GAAG,CAAC,CAAU,EAAuC,EAAE,CAC9D,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAA6B,CAAC,CAAC,CAAC,SAAS,CAAC;AAE/F,KAAK,UAAU,IAAI,CACjB,CAAoB,EACpB,GAAW,EACX,IAAiB;IAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;IACtF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1G,IAAI,GAAG,GAAY,IAAI,CAAC;QACxB,IAAI,CAAC;YACH,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAY,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,GAAG,IAAI,CAAC;QACb,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,WAAW,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/G,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAgC,EAAsB,EAAE,CAC3E,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;AAEtD;;;;;;;;;GASG;AACH,SAAgB,oBAAoB,CAClC,IAGC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACxH,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QACxC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;YAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,qBAAqB,IAAI,SAAS,CAAC;YACpD,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YACnJ,IAAI,CAAC,CAAC,YAAY;gBAAE,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;YAC9D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,WAAW,MAAM,WAAW,EAAE;gBAChE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBAC5F,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC5C,OAAO,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,eAAe,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE;YAC3E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,yBAAyB,EAAE,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,EAAE,CAAC;SAC1I,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACtD,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnF,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE;YAC1B,qFAAqF;YACrF,cAAc,EAAE,KAAK;YACrB,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC/D,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;SAC3B,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACnC,IAAuH;IAEvH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QACxC,MAAM,IAAI,GAA2B;YACnC,UAAU,EAAE,kDAAkD;YAC9D,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,UAAU;YACpB,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,QAAQ;YACxB,KAAK,EAAE,sBAAsB;SAC9B,CAAC;QACF,IAAI,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC;QAC9D,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,cAAc,EAAE;YAClD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE;YAC3E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACvG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,KAAK,cAAc,EAAE,CAAC;YAC7D,yEAAyE;YACzE,yEAAyE;YACzE,OAAO,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACtG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CACrC,IAAiE;IAEjE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,iBAAiB,CAAC,CAAC;IACvD,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QACxC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,0BAA0B,EAAE;YAC9D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,SAAS,EAAE,EAAE;YAC1F,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;SACxD,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACzD,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtF,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACjC,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE;YAC1B,cAAc,EAAE,IAAI,CAAC,aAAa,KAAK,IAAI;YAC3C,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3E,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;SAC9B,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CACnC,IAAgE;IAEhE,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,SAAS,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC9H,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QACxC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,2BAA2B,kBAAkB,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACxH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChD,mFAAmF;QACnF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,IAAK,CAAC,IAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3H,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,aAAa,kBAAkB,CAAC,EAAE,CAAC,kBAAkB,EAAE;YACzF,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,wBAAwB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7F,OAAO;YACL,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,UAAU,CAAC,CAAC,WAAW,EAAE;YAChE,cAAc,EAAE,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,UAAU;YACjE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzD,WAAW,EAAE,EAAE;SAChB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,OAA2B,EAAE,CAA8B;IACrF,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,IAAA,gBAAS,EAAC,OAAO,CAA4B,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE;QAC1B,cAAc,EAAE,MAAM,CAAC,cAAc,KAAK,IAAI;QAC9C,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACnF,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;KAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { MigrationTokenExtractor } from './migration-bridge';
2
+ /** Is this a Magic DID token by shape (`[0x…proof, claim JSON with a did:ethr iss]`)? Nothing is verified. */
3
+ export declare function looksLikeMagicDidToken(token: string): boolean;
4
+ /** The bridge token extractor for Magic: the DID token in `Authorization: Bearer`, when there is one. */
5
+ export declare function magicDidTokenExtractor(): MigrationTokenExtractor;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.looksLikeMagicDidToken = looksLikeMagicDidToken;
4
+ exports.magicDidTokenExtractor = magicDidTokenExtractor;
5
+ /**
6
+ * Magic (magic.link) DID tokens for the migration bridge. A Magic app sends
7
+ * `magic.user.getIdToken()` to its server as `Authorization: Bearer <DID token>`;
8
+ * a DID token is base64(JSON `[proof, claim]`), not a JWT, so the bridge's
9
+ * generic Bearer reading (which routes on a JWT's `iss`) does not see it.
10
+ * This extractor picks it out (by shape only — Atlas verifies the signature,
11
+ * expiry and audience on exchange). Runs on every runtime (no Buffer).
12
+ *
13
+ * migrationBridge({ source: 'magic', presetVars: { client_id }, extractToken: magicDidTokenExtractor() })
14
+ */
15
+ const ISSUER = /^did:ethr:0x[0-9a-fA-F]{40}$/;
16
+ function header(headers, name) {
17
+ if (typeof headers.get === 'function')
18
+ return headers.get(name) ?? undefined;
19
+ const record = headers;
20
+ const value = record[name] ?? record[name.toLowerCase()];
21
+ return Array.isArray(value) ? value[0] : value;
22
+ }
23
+ /** Is this a Magic DID token by shape (`[0x…proof, claim JSON with a did:ethr iss]`)? Nothing is verified. */
24
+ function looksLikeMagicDidToken(token) {
25
+ if (!token || token.length > 16_384 || !/^[A-Za-z0-9+/_-]+={0,2}$/.test(token))
26
+ return false;
27
+ try {
28
+ const b64 = token.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(token.length / 4) * 4, '=');
29
+ const outer = JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(b64), (c) => c.charCodeAt(0))));
30
+ if (!Array.isArray(outer) || outer.length !== 2 || typeof outer[0] !== 'string' || typeof outer[1] !== 'string')
31
+ return false;
32
+ if (!/^0x[0-9a-fA-F]{130}$/.test(outer[0]))
33
+ return false;
34
+ const claim = JSON.parse(outer[1]);
35
+ return typeof claim?.iss === 'string' && ISSUER.test(claim.iss);
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ /** The bridge token extractor for Magic: the DID token in `Authorization: Bearer`, when there is one. */
42
+ function magicDidTokenExtractor() {
43
+ return ({ headers }) => {
44
+ const auth = header(headers, 'authorization');
45
+ const m = auth ? /^Bearer\s+(\S+)$/i.exec(auth.trim()) : null;
46
+ return m && looksLikeMagicDidToken(m[1]) ? m[1] : undefined;
47
+ };
48
+ }
49
+ //# sourceMappingURL=magic-did.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"magic-did.js","sourceRoot":"","sources":["../src/magic-did.ts"],"names":[],"mappings":";;AAuBA,wDAYC;AAGD,wDAMC;AA1CD;;;;;;;;;GASG;AAEH,MAAM,MAAM,GAAG,8BAA8B,CAAC;AAE9C,SAAS,MAAM,CAAC,OAA0D,EAAE,IAAY;IACtF,IAAI,OAAQ,OAA6B,CAAC,GAAG,KAAK,UAAU;QAAE,OAAQ,OAAgD,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;IAC9I,MAAM,MAAM,GAAG,OAAwD,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACjD,CAAC;AAED,8GAA8G;AAC9G,SAAgB,sBAAsB,CAAC,KAAa;IAClD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACrG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAY,CAAC;QAClH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9H,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAsB,CAAC;QACxD,OAAO,OAAO,KAAK,EAAE,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,yGAAyG;AACzG,SAAgB,sBAAsB;IACpC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,OAAO,CAAC,IAAI,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,162 @@
1
+ import type { BridgeCookie } from './better-auth';
2
+ import { type TokenFormat } from './migration-presets';
3
+ /** The Frontend API exchange path for a source. */
4
+ export declare function migrationExchangePath(source: string): string;
5
+ /** The Backend API (secret-key) exchange path for a source. */
6
+ export declare function migrationBapiExchangePath(source: string): string;
7
+ /** Why Atlas refused an exchange (`meta.bridge_outcome`). */
8
+ export type MigrationBridgeRefusal = 'closed' | 'invalid' | 'signature_invalid' | 'expired' | 'reused' | 'user_unavailable' | 'user_unknown' | 'rate_limited' | 'unavailable';
9
+ export type MigrationExchangeResult = {
10
+ kind: 'session';
11
+ jwt: string;
12
+ refreshToken: string;
13
+ sessionId: string;
14
+ userId: string;
15
+ expiresIn: number;
16
+ }
17
+ /** The user still owes a second factor (or MFA enrolment) — the old session is spent. */
18
+ | {
19
+ kind: 'needs_mfa';
20
+ attemptId: string;
21
+ status: 'needs_second_factor' | 'needs_mfa_enrollment';
22
+ } | {
23
+ kind: 'refused';
24
+ outcome: MigrationBridgeRefusal;
25
+ status: number;
26
+ };
27
+ export interface ExchangeMigrationSessionOptions {
28
+ /** The migration source (`auth0`, `clerk`, `cognito`, `better_auth` …). */
29
+ source: string;
30
+ /** The instance's Frontend API origin. */
31
+ fapiOrigin: string;
32
+ publishableKey: string;
33
+ /**
34
+ * The instance secret key. When set (recommended on a server) the exchange
35
+ * goes to the Backend API — limited per instance with a ceiling sized for a
36
+ * bulk cutover, not per IP — and takes the user's IP / user agent from
37
+ * `clientIp` / `userAgent`.
38
+ */
39
+ secretKey?: string;
40
+ /** Backend API origin for the secret-key path. Default `https://api.atlasauth.net`. */
41
+ bapiBaseUrl?: string;
42
+ clientIp?: string;
43
+ /** The old session token as read from the cookie / header (after the preset's token format). */
44
+ token: string;
45
+ remember?: boolean;
46
+ fetchImpl?: typeof fetch;
47
+ userAgent?: string;
48
+ }
49
+ /**
50
+ * Exchange an old vendor session for an Atlas session, server to server
51
+ * (`delivery: "body"`). Never throws: a transport failure is
52
+ * `{ kind: 'refused', outcome: 'unavailable' }`, so the caller keeps the old
53
+ * cookie and tries again on a later request.
54
+ */
55
+ export declare function exchangeMigrationSession(options: ExchangeMigrationSessionOptions): Promise<MigrationExchangeResult>;
56
+ type HeaderBag = {
57
+ get(name: string): string | null;
58
+ } | Record<string, string | string[] | undefined>;
59
+ /** Everything the bridge sees of a request. */
60
+ export interface MigrationBridgeRequest {
61
+ headers: HeaderBag;
62
+ /** The end user's IP as your framework resolved it (forwarded on the secret-key path). */
63
+ ip?: string;
64
+ }
65
+ /**
66
+ * Pull the old token out of a request yourself — for a vendor whose cookie is
67
+ * encrypted with a secret only your server has (nextjs-auth0, WorkOS AuthKit,
68
+ * Auth.js JWT sessions): open it locally and return the JWT inside. Return
69
+ * undefined when the request carries no old session.
70
+ */
71
+ export type MigrationTokenExtractor = (input: {
72
+ cookies: Record<string, string>;
73
+ headers: HeaderBag;
74
+ }) => string | undefined | Promise<string | undefined>;
75
+ export interface MigrationBridgeOptions {
76
+ /** The migration source (`auth0`, `clerk`, `cognito`, `supabase`, `better_auth` …). */
77
+ source: string;
78
+ fapiOrigin: string;
79
+ publishableKey: string;
80
+ /** The instance secret key: exchanges go through the Backend API (recommended). */
81
+ secretKey?: string;
82
+ bapiBaseUrl?: string;
83
+ /** The bridge preset (default: the preset named like the source). */
84
+ preset?: string;
85
+ /** Variables the preset's cookie names need (`project_ref`, `client_id`, `cookie_prefix` …). */
86
+ presetVars?: Record<string, string>;
87
+ /** Cookie names to read, instead of the preset's (`*` wildcards allowed). */
88
+ cookieNames?: string[];
89
+ /** Cookie names to clear after an exchange, instead of the preset's. */
90
+ clearCookieNames?: string[];
91
+ /** How the cookie holds the token (`raw`, `supabase`); default the preset's. */
92
+ tokenFormat?: TokenFormat;
93
+ /** A custom extractor; replaces cookie reading entirely. */
94
+ extractToken?: MigrationTokenExtractor;
95
+ /** Also read `Authorization: Bearer` (default: the preset's choice). */
96
+ bearer?: boolean;
97
+ /** The `domain` the old cookies were set on, so they clear. */
98
+ oldCookieDomain?: string;
99
+ /** Mark the Atlas cookies `Secure`. Default true; false only for plain-http local development. */
100
+ secure?: boolean;
101
+ fetchImpl?: typeof fetch;
102
+ }
103
+ /** What the bridge decided for one request. */
104
+ export type MigrationBridgeDecision =
105
+ /** No old session, or an Atlas session already present: carry on. */
106
+ {
107
+ action: 'none';
108
+ }
109
+ /** Exchanged: set these cookies and re-enter (redirect to the same URL) so the new session is read. */
110
+ | {
111
+ action: 'signed_in';
112
+ cookies: BridgeCookie[];
113
+ session: Extract<MigrationExchangeResult, {
114
+ kind: 'session';
115
+ }>;
116
+ }
117
+ /** A second factor is owed: send the browser to your sign-in page carrying the attempt. */
118
+ | {
119
+ action: 'needs_mfa';
120
+ cookies: BridgeCookie[];
121
+ attemptId: string;
122
+ status: string;
123
+ continuationUrl: (url: string) => string;
124
+ }
125
+ /** Refused. `cookies` clears the old cookies when the refusal is final. */
126
+ | {
127
+ action: 'refused';
128
+ cookies: BridgeCookie[];
129
+ outcome: MigrationBridgeRefusal;
130
+ };
131
+ /** Parse a Cookie header into name → raw value (first occurrence wins). */
132
+ export declare function parseCookieHeader(cookieHeader: string | null | undefined): Record<string, string>;
133
+ /** The token in the PocketBase JS SDK's `authStore.exportToCookie()` cookie (`pb_auth`: JSON `{ token, record }`). */
134
+ export declare function readPocketBaseCookieToken(raw: string | undefined): string | undefined;
135
+ /**
136
+ * Supabase SSR cookie: `sb-<ref>-auth-token` (or chunks `.0`, `.1`, … joined in
137
+ * order), the value JSON or `base64-` + base64url(JSON), holding `access_token`.
138
+ */
139
+ export declare function readSupabaseAccessToken(cookies: Record<string, string>, baseName: string): string | undefined;
140
+ /**
141
+ * The refresh token in the same cookie (`refresh_token`, or the second entry
142
+ * of the older auth-helpers array): what the `supabase_refresh_token`
143
+ * session-table preset looks up among the sessions a dump of
144
+ * auth.refresh_tokens imported.
145
+ */
146
+ export declare function readSupabaseRefreshToken(cookies: Record<string, string>, baseName: string): string | undefined;
147
+ /** Resolve the cookie names / format / bearer flag the bridge uses for its source. */
148
+ export declare function bridgeCookieConfig(options: Pick<MigrationBridgeOptions, 'source' | 'preset' | 'presetVars' | 'cookieNames' | 'clearCookieNames' | 'tokenFormat' | 'bearer'>): {
149
+ cookies: string[];
150
+ clear: string[];
151
+ format: TokenFormat;
152
+ bearer: boolean;
153
+ sharesAtlasCookie: boolean;
154
+ issuer: string | null;
155
+ };
156
+ /**
157
+ * The bridge as a function of a request's headers. Call it from middleware
158
+ * before your normal auth check; it does nothing (no network) for a request
159
+ * without an old session, or with an Atlas session already present.
160
+ */
161
+ export declare function createMigrationBridge(options: MigrationBridgeOptions): (request: MigrationBridgeRequest) => Promise<MigrationBridgeDecision>;
162
+ export {};