@atlasauth/backend 0.15.0 → 0.17.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 (56) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/better-auth.d.ts +157 -0
  3. package/dist/better-auth.js +245 -0
  4. package/dist/better-auth.js.map +1 -0
  5. package/dist/botid.d.ts +70 -0
  6. package/dist/botid.js +88 -0
  7. package/dist/botid.js.map +1 -0
  8. package/dist/client/action-gallery.d.ts +215 -0
  9. package/dist/client/action-gallery.js +66 -0
  10. package/dist/client/action-gallery.js.map +1 -0
  11. package/dist/client/actions.d.ts +21 -0
  12. package/dist/client/actions.js.map +1 -1
  13. package/dist/client/attack-protection.d.ts +33 -1
  14. package/dist/client/attack-protection.js.map +1 -1
  15. package/dist/client/better-auth-imports.d.ts +205 -0
  16. package/dist/client/better-auth-imports.js +107 -0
  17. package/dist/client/better-auth-imports.js.map +1 -0
  18. package/dist/client/billing-plans.d.ts +93 -0
  19. package/dist/client/billing-plans.js +31 -0
  20. package/dist/client/billing-plans.js.map +1 -1
  21. package/dist/client/custom-oauth-providers.d.ts +243 -0
  22. package/dist/client/custom-oauth-providers.js +60 -0
  23. package/dist/client/custom-oauth-providers.js.map +1 -0
  24. package/dist/client/email-templates.d.ts +1 -1
  25. package/dist/client/email-templates.js.map +1 -1
  26. package/dist/client/index.d.ts +154 -0
  27. package/dist/client/index.js +11 -0
  28. package/dist/client/index.js.map +1 -1
  29. package/dist/client/instance-security.d.ts +70 -0
  30. package/dist/client/instance-security.js +20 -0
  31. package/dist/client/instance-security.js.map +1 -1
  32. package/dist/client/oauth-clients.d.ts +29 -2
  33. package/dist/client/oauth-clients.js.map +1 -1
  34. package/dist/client/resource-servers.d.ts +22 -2
  35. package/dist/client/resource-servers.js.map +1 -1
  36. package/dist/client/risk-based-mfa.d.ts +3 -0
  37. package/dist/client/risk-based-mfa.js.map +1 -1
  38. package/dist/client/sessions.d.ts +16 -0
  39. package/dist/client/sessions.js +15 -0
  40. package/dist/client/sessions.js.map +1 -1
  41. package/dist/client/sso-connections.d.ts +83 -0
  42. package/dist/client/sso-connections.js +29 -0
  43. package/dist/client/sso-connections.js.map +1 -1
  44. package/dist/index.d.ts +6 -2
  45. package/dist/index.js +11 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/legacy-issuers.d.ts +65 -0
  48. package/dist/legacy-issuers.js +140 -0
  49. package/dist/legacy-issuers.js.map +1 -0
  50. package/dist/oauth-resource.d.ts +81 -1
  51. package/dist/oauth-resource.js +204 -29
  52. package/dist/oauth-resource.js.map +1 -1
  53. package/dist/verify.d.ts +22 -0
  54. package/dist/verify.js +32 -0
  55. package/dist/verify.js.map +1 -1
  56. package/package.json +3 -3
@@ -17,6 +17,8 @@ export interface Session {
17
17
  */
18
18
  idle_expires_at?: number;
19
19
  created_at: number;
20
+ /** Custom per-session data your backend (or a post_login Action) attached; null when none. */
21
+ custom_data?: Record<string, unknown> | null;
20
22
  }
21
23
  /** The session after a keep-alive {@link sessionsResource} `touch`. */
22
24
  export interface TouchedSession extends Session {
@@ -35,6 +37,8 @@ export interface CreateSessionParams {
35
37
  actor?: {
36
38
  sub: string;
37
39
  };
40
+ /** Custom per-session data to attach (a JSON object, at most 2 KB). */
41
+ custom_data?: Record<string, unknown>;
38
42
  }
39
43
  /**
40
44
  * A freshly-minted session. Unlike a listed {@link Session}, this carries the
@@ -52,6 +56,7 @@ export interface MintedSession {
52
56
  impersonated_by?: {
53
57
  sub: string;
54
58
  };
59
+ custom_data?: Record<string, unknown> | null;
55
60
  }
56
61
  /** A JWT minted from a named JWT template. */
57
62
  export interface SessionTemplateToken {
@@ -74,6 +79,17 @@ export declare function sessionsResource(request: RequestFn): {
74
79
  id: string;
75
80
  status: "revoked";
76
81
  }>;
82
+ /**
83
+ * `PUT /v1/sessions/:id/custom_data` — replace the session's custom data
84
+ * (null clears it). At most 2 KB; only an active session can be changed.
85
+ * Not for secrets: the signed-in user can read it.
86
+ */
87
+ setCustomData(id: string, customData: Record<string, unknown> | null): Promise<Session>;
88
+ /**
89
+ * `PATCH /v1/sessions/:id/custom_data` — merge keys into the session's custom
90
+ * data; a key set to null is removed.
91
+ */
92
+ updateCustomData(id: string, patch: Record<string, unknown>): Promise<Session>;
77
93
  /**
78
94
  * `POST /v1/sessions/:id/touch` — keep a session alive from your backend:
79
95
  * slides its inactivity window as if the user had just loaded a page. Never
@@ -21,6 +21,21 @@ function sessionsResource(request) {
21
21
  revoke(id) {
22
22
  return request({ method: 'POST', path: `/v1/sessions/${(0, request_1.enc)(id)}/revoke` });
23
23
  },
24
+ /**
25
+ * `PUT /v1/sessions/:id/custom_data` — replace the session's custom data
26
+ * (null clears it). At most 2 KB; only an active session can be changed.
27
+ * Not for secrets: the signed-in user can read it.
28
+ */
29
+ setCustomData(id, customData) {
30
+ return request({ method: 'PUT', path: `/v1/sessions/${(0, request_1.enc)(id)}/custom_data`, body: { custom_data: customData } });
31
+ },
32
+ /**
33
+ * `PATCH /v1/sessions/:id/custom_data` — merge keys into the session's custom
34
+ * data; a key set to null is removed.
35
+ */
36
+ updateCustomData(id, patch) {
37
+ return request({ method: 'PATCH', path: `/v1/sessions/${(0, request_1.enc)(id)}/custom_data`, body: { custom_data: patch } });
38
+ },
24
39
  /**
25
40
  * `POST /v1/sessions/:id/touch` — keep a session alive from your backend:
26
41
  * slides its inactivity window as if the user had just loaded a page. Never
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/client/sessions.ts"],"names":[],"mappings":";;AAiEA,4CAwCC;AAzGD,uCAAgD;AAiEhD,SAAgB,gBAAgB,CAAC,OAAkB;IACjD,OAAO;QACL;;;WAGG;QACH,MAAM,CAAC,MAA2B;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,wDAAwD;QACxD,IAAI,CAAC,MAA0B;YAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD;;;;;;WAMG;QACH,KAAK,CAAC,EAAU;YACd,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD;;;WAGG;QACH,QAAQ,CAAC,EAAU,EAAE,QAAgB;YACnC,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,WAAW,IAAA,aAAG,EAAC,QAAQ,CAAC,EAAE;aACxD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/client/sessions.ts"],"names":[],"mappings":";;AAsEA,4CAuDC;AA7HD,uCAAgD;AAsEhD,SAAgB,gBAAgB,CAAC,OAAkB;IACjD,OAAO;QACL;;;WAGG;QACH,MAAM,CAAC,MAA2B;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,wDAAwD;QACxD,IAAI,CAAC,MAA0B;YAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD;;;;WAIG;QACH,aAAa,CAAC,EAAU,EAAE,UAA0C;YAClE,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QACpH,CAAC;QACD;;;WAGG;QACH,gBAAgB,CAAC,EAAU,EAAE,KAA8B;YACzD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACjH,CAAC;QACD;;;;;;WAMG;QACH,KAAK,CAAC,EAAU;YACd,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD;;;WAGG;QACH,QAAQ,CAAC,EAAU,EAAE,QAAgB;YACnC,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,gBAAgB,IAAA,aAAG,EAAC,EAAE,CAAC,WAAW,IAAA,aAAG,EAAC,QAAQ,CAAC,EAAE;aACxD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { type RequestFn } from './request';
2
2
  import type { ListPage } from './types';
3
+ import { type IdpInitiatedLoginSettings, type ProfileMapping, type ProfileMappingPreview, type ProfileMappingPreviewBody, type TokenEndpointAuthMethod, type UpstreamLogoutSettings, type UpstreamUrls } from './custom-oauth-providers';
3
4
  export interface ClaimRoleMapping {
4
5
  claim: string;
5
6
  value: string;
@@ -22,6 +23,21 @@ export interface SsoConnection {
22
23
  saml_allow_idp_initiated: boolean;
23
24
  saml_sign_authn_requests: boolean;
24
25
  saml_want_response_signed: boolean;
26
+ /** SAML Single Logout is on for the connection. */
27
+ saml_single_logout?: boolean;
28
+ /** The IdP SingleLogoutService Location / ResponseLocation and delivery binding. */
29
+ saml_idp_slo_url?: string | null;
30
+ saml_idp_slo_response_url?: string | null;
31
+ saml_idp_slo_binding?: 'redirect' | 'post';
32
+ /** The IdP SOAP SingleLogoutService — the back channel for sessions ended server-side. */
33
+ saml_idp_slo_soap_url?: string | null;
34
+ /** Assertions that are not encrypted to the connection's key are refused. */
35
+ saml_require_encrypted_assertions?: boolean;
36
+ /** An SP encryption key pair is set up (the private key is never returned). */
37
+ has_saml_encryption_key?: boolean;
38
+ /** A key rotation is in progress (the previous key is still accepted). */
39
+ has_previous_saml_encryption_key?: boolean;
40
+ saml_encryption_rotated_at?: number | null;
25
41
  has_discourse_secret: boolean;
26
42
  discourse_provider_url: string | null;
27
43
  allowed_domains: string[];
@@ -31,6 +47,14 @@ export interface SsoConnection {
31
47
  attribute_mapping?: SsoAttributeMapping;
32
48
  /** OIDC: extra scopes requested on top of openid email profile. */
33
49
  oidc_scopes?: string[];
50
+ /** OIDC relying-party settings (see custom OAuth providers). */
51
+ profile_mapping?: Required<ProfileMapping> | null;
52
+ token_endpoint_auth_method?: TokenEndpointAuthMethod | null;
53
+ client_assertion_audience?: string | null;
54
+ logout?: Required<UpstreamLogoutSettings>;
55
+ idp_initiated_login?: Required<IdpInitiatedLoginSettings>;
56
+ /** OIDC connections: the URLs to register at the IdP. */
57
+ upstream_urls?: UpstreamUrls | null;
34
58
  /** Routing domains of an org-owned connection that the org has not verified. */
35
59
  domain_warnings?: Array<{
36
60
  domain: string;
@@ -43,9 +67,23 @@ export interface SamlMetadata {
43
67
  object: 'sso_saml_metadata';
44
68
  sp_entity_id: string;
45
69
  acs_url: string;
70
+ /** Our SingleLogoutService URL (both bindings), when Single Logout is on. */
71
+ slo_url?: string | null;
46
72
  /** The SP EntityDescriptor XML, carried as a string inside this JSON envelope. */
47
73
  metadata_xml: string;
48
74
  }
75
+ /** A SAML connection's SP encryption key pair — certificates only. */
76
+ export interface SamlEncryptionKey {
77
+ object: 'sso_saml_encryption_key';
78
+ connection_id: string;
79
+ /** The current certificate (PEM), published in SP metadata; null when encryption is off. */
80
+ certificate: string | null;
81
+ /** The previous certificate during a rotation; null otherwise. */
82
+ previous_certificate: string | null;
83
+ /** When the current key was installed (epoch ms). */
84
+ rotated_at: number | null;
85
+ require_encrypted_assertions: boolean;
86
+ }
49
87
  export interface CreateSsoConnectionBody {
50
88
  organization_id?: string | null;
51
89
  type?: 'oidc' | 'saml' | 'discourse' | 'discourse_consumer';
@@ -62,6 +100,16 @@ export interface CreateSsoConnectionBody {
62
100
  saml_allow_idp_initiated?: boolean;
63
101
  saml_sign_authn_requests?: boolean;
64
102
  saml_want_response_signed?: boolean;
103
+ /** SAML Single Logout on/off. */
104
+ saml_single_logout?: boolean;
105
+ /** https; null clears it. Filled by IdP metadata import when published. */
106
+ saml_idp_slo_url?: string | null;
107
+ saml_idp_slo_response_url?: string | null;
108
+ saml_idp_slo_binding?: 'redirect' | 'post' | null;
109
+ /** https; null clears it. The back channel for sessions ended server-side. */
110
+ saml_idp_slo_soap_url?: string | null;
111
+ /** Requires an encryption key (see `createSamlEncryptionKey`). */
112
+ saml_require_encrypted_assertions?: boolean;
65
113
  discourse_secret?: string;
66
114
  discourse_provider_url?: string;
67
115
  allowed_domains?: string[];
@@ -71,6 +119,15 @@ export interface CreateSsoConnectionBody {
71
119
  attribute_mapping?: SsoAttributeMapping | null;
72
120
  /** OIDC only; null clears them. */
73
121
  oidc_scopes?: string[] | null;
122
+ /** OIDC: declarative profile mapping; null clears it. */
123
+ profile_mapping?: ProfileMapping | null;
124
+ /** OIDC: token-endpoint client authentication (private_key_jwt needs no secret). */
125
+ token_endpoint_auth_method?: TokenEndpointAuthMethod | null;
126
+ client_assertion_audience?: string | null;
127
+ /** OIDC: RP-initiated and back-channel logout. */
128
+ logout?: UpstreamLogoutSettings | null;
129
+ /** OIDC: third-party initiated login. */
130
+ idp_initiated_login?: IdpInitiatedLoginSettings | null;
74
131
  }
75
132
  /** Claim (OIDC) or attribute (SAML) names for each profile field. */
76
133
  export interface SsoAttributeMapping {
@@ -93,6 +150,32 @@ export declare function ssoConnectionsResource(request: RequestFn): {
93
150
  id: string;
94
151
  deleted: true;
95
152
  }>;
153
+ /** OIDC: run the connection's profile mapping (or the body's) against a pasted sample. */
154
+ previewProfileMapping(id: string, body: ProfileMappingPreviewBody): Promise<ProfileMappingPreview>;
155
+ /** OIDC: the connection's private_key_jwt signing keys. */
156
+ signingKeys(id: string): {
157
+ list(): Promise<ListPage<import("./custom-oauth-providers").UpstreamSigningKey>>;
158
+ rotate(body?: {
159
+ alg?: "RS256" | "PS256" | "ES256";
160
+ }, idempotencyKey?: string): Promise<import("./custom-oauth-providers").UpstreamSigningKey>;
161
+ retire(kid: string): Promise<{
162
+ object: "upstream_signing_key";
163
+ kid: string;
164
+ status: "retired";
165
+ }>;
166
+ };
96
167
  /** SP SAML metadata for a connection (JSON envelope carrying the XML). */
97
168
  samlMetadata(id: string): Promise<SamlMetadata>;
169
+ /** The SAML connection's SP encryption certificate(s). */
170
+ getSamlEncryptionKey(id: string): Promise<SamlEncryptionKey>;
171
+ /**
172
+ * Generate the SP encryption key pair, or ROTATE it when one exists: the
173
+ * current pair becomes the previous one (still advertised and accepted until
174
+ * {@link retirePreviousSamlEncryptionKey}).
175
+ */
176
+ createSamlEncryptionKey(id: string, idempotencyKey?: string): Promise<SamlEncryptionKey>;
177
+ /** Finish a rotation: stop accepting the previous encryption key. */
178
+ retirePreviousSamlEncryptionKey(id: string): Promise<SamlEncryptionKey>;
179
+ /** Turn assertion encryption off (refused while encrypted assertions are required). */
180
+ deleteSamlEncryptionKey(id: string): Promise<SamlEncryptionKey>;
98
181
  };
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ssoConnectionsResource = ssoConnectionsResource;
4
4
  const request_1 = require("./request");
5
+ const custom_oauth_providers_1 = require("./custom-oauth-providers");
5
6
  function ssoConnectionsResource(request) {
6
7
  return {
7
8
  list() {
@@ -19,10 +20,38 @@ function ssoConnectionsResource(request) {
19
20
  delete(id) {
20
21
  return request({ method: 'DELETE', path: `/v1/sso_connections/${(0, request_1.enc)(id)}` });
21
22
  },
23
+ /** OIDC: run the connection's profile mapping (or the body's) against a pasted sample. */
24
+ previewProfileMapping(id, body) {
25
+ return request({ method: 'POST', path: `/v1/sso_connections/${(0, request_1.enc)(id)}/profile_mapping/preview`, body });
26
+ },
27
+ /** OIDC: the connection's private_key_jwt signing keys. */
28
+ signingKeys(id) {
29
+ return (0, custom_oauth_providers_1.upstreamSigningKeys)(request, `/v1/sso_connections/${(0, request_1.enc)(id)}`);
30
+ },
22
31
  /** SP SAML metadata for a connection (JSON envelope carrying the XML). */
23
32
  samlMetadata(id) {
24
33
  return request({ method: 'GET', path: `/v1/sso_connections/${(0, request_1.enc)(id)}/saml_metadata` });
25
34
  },
35
+ /** The SAML connection's SP encryption certificate(s). */
36
+ getSamlEncryptionKey(id) {
37
+ return request({ method: 'GET', path: `/v1/sso_connections/${(0, request_1.enc)(id)}/saml_encryption_key` });
38
+ },
39
+ /**
40
+ * Generate the SP encryption key pair, or ROTATE it when one exists: the
41
+ * current pair becomes the previous one (still advertised and accepted until
42
+ * {@link retirePreviousSamlEncryptionKey}).
43
+ */
44
+ createSamlEncryptionKey(id, idempotencyKey) {
45
+ return request({ method: 'POST', path: `/v1/sso_connections/${(0, request_1.enc)(id)}/saml_encryption_key`, idempotencyKey });
46
+ },
47
+ /** Finish a rotation: stop accepting the previous encryption key. */
48
+ retirePreviousSamlEncryptionKey(id) {
49
+ return request({ method: 'DELETE', path: `/v1/sso_connections/${(0, request_1.enc)(id)}/saml_encryption_key/previous` });
50
+ },
51
+ /** Turn assertion encryption off (refused while encrypted assertions are required). */
52
+ deleteSamlEncryptionKey(id) {
53
+ return request({ method: 'DELETE', path: `/v1/sso_connections/${(0, request_1.enc)(id)}/saml_encryption_key` });
54
+ },
26
55
  };
27
56
  }
28
57
  //# sourceMappingURL=sso-connections.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sso-connections.js","sourceRoot":"","sources":["../../src/client/sso-connections.ts"],"names":[],"mappings":";;AAyFA,wDAsBC;AA/GD,uCAAgD;AAyFhD,SAAgB,sBAAsB,CAAC,OAAkB;IACvD,OAAO;QACL,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,IAA6B,EAAE,cAAuB;YAC3D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,CAAC,EAAU,EAAE,IAA6B;YAC9C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,0EAA0E;QAC1E,YAAY,CAAC,EAAU;YACrB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC1F,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"sso-connections.js","sourceRoot":"","sources":["../../src/client/sso-connections.ts"],"names":[],"mappings":";;AA4JA,wDAkDC;AA9MD,uCAAgD;AAEhD,qEASkC;AAiJlC,SAAgB,sBAAsB,CAAC,OAAkB;IACvD,OAAO;QACL,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,IAA6B,EAAE,cAAuB;YAC3D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,CAAC,EAAU,EAAE,IAA6B;YAC9C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,0FAA0F;QAC1F,qBAAqB,CAAC,EAAU,EAAE,IAA+B;YAC/D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,0BAA0B,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,2DAA2D;QAC3D,WAAW,CAAC,EAAU;YACpB,OAAO,IAAA,4CAAmB,EAAC,OAAO,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,0EAA0E;QAC1E,YAAY,CAAC,EAAU;YACrB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,0DAA0D;QAC1D,oBAAoB,CAAC,EAAU;YAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,sBAAsB,EAAE,CAAC,CAAC;QAChG,CAAC;QACD;;;;WAIG;QACH,uBAAuB,CAAC,EAAU,EAAE,cAAuB;YACzD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,sBAAsB,EAAE,cAAc,EAAE,CAAC,CAAC;QACjH,CAAC;QACD,qEAAqE;QACrE,+BAA+B,CAAC,EAAU;YACxC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,+BAA+B,EAAE,CAAC,CAAC;QAC5G,CAAC;QACD,uFAAuF;QACvF,uBAAuB,CAAC,EAAU;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,EAAE,CAAC,sBAAsB,EAAE,CAAC,CAAC;QACnG,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,12 +3,16 @@ export { DiscoveryError, JwksDiscovery, discoveryUrlFor, instanceIdFromPublishab
3
3
  export * from './verify';
4
4
  export * from './access-control';
5
5
  export * from './handshake';
6
+ export * from './better-auth';
7
+ export { BETTER_AUTH_JWT_ALGS, peekIssuer } from './legacy-issuers';
8
+ export type { LegacyIssuer } from './legacy-issuers';
6
9
  export { BACKCHANNEL_LOGOUT_EVENT, LOGOUT_TOKEN_CLOCK_SKEW_SECONDS, LOGOUT_TOKEN_MAX_AGE_SECONDS, LogoutTokenVerifier, memoryLogoutReplayStore, verifyLogoutToken, } from './logout-token';
7
10
  export type { LogoutReplayStore, LogoutTokenCheckOptions, LogoutTokenClaims, LogoutTokenResult, LogoutTokenVerifierOptions, } from './logout-token';
8
11
  export { AtlasOidcError, OIDC_FLOW_COOKIE, OIDC_FLOW_MAX_AGE_SECONDS, oidc, oidcCallback, oidcClearCookie, oidcLogoutUrl, oidcStart, oidcVerifyIdToken, resetOidcCaches, } from './oidc';
9
12
  export type { AtlasOidc, AtlasOidcErrorCode, OidcCallbackOptions, OidcClientAuth, OidcIdentity, OidcLogoutUrlOptions, OidcStartOptions, OidcStartResult, VerifyIdTokenOptions, } from './oidc';
10
13
  export * from './webhooks';
11
14
  export * from './referrals';
15
+ export * from './botid';
12
16
  export { createAtlasClient } from './client';
13
17
  export type { AtlasClient } from './client';
14
18
  export * from './client';
@@ -20,5 +24,5 @@ export { verifyPCActn } from './pca/verify';
20
24
  export type { PcaVerdict, PcaContext, VerifyPCActnOptions } from './pca/verify';
21
25
  export { requirePCA, defaultExtract, memoryPcaStore } from './pca/require-pca';
22
26
  export type { RequirePcaOptions, PcaGuardResult, PcaRequestLike, PcaStateStore } from './pca/require-pca';
23
- export { ACCESS_TOKEN_CLOCK_SKEW_SECONDS, DPOP_PROOF_MAX_AGE_SECONDS, buildWwwAuthenticate, createAccessTokenVerifier, memoryDpopReplayStore, protectedResourceMetadata, protectedResourceMetadataPath, verifyAccessToken, } from './oauth-resource';
24
- export type { AccessTokenClaims, AccessTokenErrorCode, AccessTokenResult, AccessTokenVerifierOptions, DpopReplayStore, ResourceRequestLike, } from './oauth-resource';
27
+ export { ACCESS_TOKEN_CLOCK_SKEW_SECONDS, DPOP_PROOF_MAX_AGE_SECONDS, buildWwwAuthenticate, createAccessTokenVerifier, createIntrospector, hmacDpopNonceSource, memoryDpopNonceSource, memoryDpopReplayStore, protectedResourceMetadata, protectedResourceMetadataPath, verifyAccessToken, } from './oauth-resource';
28
+ export type { AccessTokenClaims, AccessTokenErrorCode, AccessTokenResult, AccessTokenVerifierOptions, DpopNonceSource, DpopReplayStore, IntrospectionOptions, ResourceRequestLike, } from './oauth-resource';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.verifyAccessToken = exports.protectedResourceMetadataPath = exports.protectedResourceMetadata = exports.memoryDpopReplayStore = exports.createAccessTokenVerifier = exports.buildWwwAuthenticate = exports.DPOP_PROOF_MAX_AGE_SECONDS = exports.ACCESS_TOKEN_CLOCK_SKEW_SECONDS = exports.memoryPcaStore = exports.defaultExtract = exports.requirePCA = exports.verifyPCActn = exports.REFERALLY_API_VERSION = exports.referralEmailHash = exports.referallySignature = exports.signReferralUpdatedEvent = exports.signReferallyCall = exports.signAtlasReferralCall = exports.TEST_TOKEN_TAMPERS = exports.createTestIssuer = exports.createAtlasClient = exports.resetOidcCaches = exports.oidcVerifyIdToken = exports.oidcStart = exports.oidcLogoutUrl = exports.oidcClearCookie = exports.oidcCallback = exports.oidc = exports.OIDC_FLOW_MAX_AGE_SECONDS = exports.OIDC_FLOW_COOKIE = exports.AtlasOidcError = exports.verifyLogoutToken = exports.memoryLogoutReplayStore = exports.LogoutTokenVerifier = exports.LOGOUT_TOKEN_MAX_AGE_SECONDS = exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS = exports.BACKCHANNEL_LOGOUT_EVENT = exports.instanceIdFromPublishableKey = exports.discoveryUrlFor = exports.JwksDiscovery = exports.DiscoveryError = void 0;
17
+ exports.verifyAccessToken = exports.protectedResourceMetadataPath = exports.protectedResourceMetadata = exports.memoryDpopReplayStore = exports.memoryDpopNonceSource = exports.hmacDpopNonceSource = exports.createIntrospector = exports.createAccessTokenVerifier = exports.buildWwwAuthenticate = exports.DPOP_PROOF_MAX_AGE_SECONDS = exports.ACCESS_TOKEN_CLOCK_SKEW_SECONDS = exports.memoryPcaStore = exports.defaultExtract = exports.requirePCA = exports.verifyPCActn = exports.REFERALLY_API_VERSION = exports.referralEmailHash = exports.referallySignature = exports.signReferralUpdatedEvent = exports.signReferallyCall = exports.signAtlasReferralCall = exports.TEST_TOKEN_TAMPERS = exports.createTestIssuer = exports.createAtlasClient = exports.resetOidcCaches = exports.oidcVerifyIdToken = exports.oidcStart = exports.oidcLogoutUrl = exports.oidcClearCookie = exports.oidcCallback = exports.oidc = exports.OIDC_FLOW_MAX_AGE_SECONDS = exports.OIDC_FLOW_COOKIE = exports.AtlasOidcError = exports.verifyLogoutToken = exports.memoryLogoutReplayStore = exports.LogoutTokenVerifier = exports.LOGOUT_TOKEN_MAX_AGE_SECONDS = exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS = exports.BACKCHANNEL_LOGOUT_EVENT = exports.peekIssuer = exports.BETTER_AUTH_JWT_ALGS = exports.instanceIdFromPublishableKey = exports.discoveryUrlFor = exports.JwksDiscovery = exports.DiscoveryError = void 0;
18
18
  // §7.3 token verification — the original surface, unchanged.
19
19
  __exportStar(require("./jwks-cache"), exports);
20
20
  // OIDC discovery of the JWKS URL when only `issuer` is configured.
@@ -26,6 +26,11 @@ Object.defineProperty(exports, "instanceIdFromPublishableKey", { enumerable: tru
26
26
  __exportStar(require("./verify"), exports);
27
27
  __exportStar(require("./access-control"), exports);
28
28
  __exportStar(require("./handshake"), exports);
29
+ // Moving from Better Auth: exchange its session cookie once, accept its JWTs for a window.
30
+ __exportStar(require("./better-auth"), exports);
31
+ var legacy_issuers_1 = require("./legacy-issuers");
32
+ Object.defineProperty(exports, "BETTER_AUTH_JWT_ALGS", { enumerable: true, get: function () { return legacy_issuers_1.BETTER_AUTH_JWT_ALGS; } });
33
+ Object.defineProperty(exports, "peekIssuer", { enumerable: true, get: function () { return legacy_issuers_1.peekIssuer; } });
29
34
  // OIDC Back-Channel Logout: verify the logout_token Atlas POSTs to your app.
30
35
  var logout_token_1 = require("./logout-token");
31
36
  Object.defineProperty(exports, "BACKCHANNEL_LOGOUT_EVENT", { enumerable: true, get: function () { return logout_token_1.BACKCHANNEL_LOGOUT_EVENT; } });
@@ -51,6 +56,8 @@ Object.defineProperty(exports, "resetOidcCaches", { enumerable: true, get: funct
51
56
  __exportStar(require("./webhooks"), exports);
52
57
  // The Atlas referral protocol, for a referral platform receiving Atlas's signed calls.
53
58
  __exportStar(require("./referrals"), exports);
59
+ // Vercel BotID: sign checkBotId() verdicts on your Vercel route for Atlas's captcha gate.
60
+ __exportStar(require("./botid"), exports);
54
61
  // The typed management client for the secret-key Backend API.
55
62
  var client_1 = require("./client");
56
63
  Object.defineProperty(exports, "createAtlasClient", { enumerable: true, get: function () { return client_1.createAtlasClient; } });
@@ -83,6 +90,9 @@ Object.defineProperty(exports, "ACCESS_TOKEN_CLOCK_SKEW_SECONDS", { enumerable:
83
90
  Object.defineProperty(exports, "DPOP_PROOF_MAX_AGE_SECONDS", { enumerable: true, get: function () { return oauth_resource_1.DPOP_PROOF_MAX_AGE_SECONDS; } });
84
91
  Object.defineProperty(exports, "buildWwwAuthenticate", { enumerable: true, get: function () { return oauth_resource_1.buildWwwAuthenticate; } });
85
92
  Object.defineProperty(exports, "createAccessTokenVerifier", { enumerable: true, get: function () { return oauth_resource_1.createAccessTokenVerifier; } });
93
+ Object.defineProperty(exports, "createIntrospector", { enumerable: true, get: function () { return oauth_resource_1.createIntrospector; } });
94
+ Object.defineProperty(exports, "hmacDpopNonceSource", { enumerable: true, get: function () { return oauth_resource_1.hmacDpopNonceSource; } });
95
+ Object.defineProperty(exports, "memoryDpopNonceSource", { enumerable: true, get: function () { return oauth_resource_1.memoryDpopNonceSource; } });
86
96
  Object.defineProperty(exports, "memoryDpopReplayStore", { enumerable: true, get: function () { return oauth_resource_1.memoryDpopReplayStore; } });
87
97
  Object.defineProperty(exports, "protectedResourceMetadata", { enumerable: true, get: function () { return oauth_resource_1.protectedResourceMetadata; } });
88
98
  Object.defineProperty(exports, "protectedResourceMetadataPath", { enumerable: true, get: function () { return oauth_resource_1.protectedResourceMetadataPath; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,mEAAmE;AACnE,yCAA2G;AAAlG,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,yHAAA,4BAA4B,OAAA;AACrF,2CAAyB;AACzB,mDAAiC;AACjC,8CAA4B;AAE5B,6EAA6E;AAC7E,+CAOwB;AANtB,wHAAA,wBAAwB,OAAA;AACxB,+HAAA,+BAA+B,OAAA;AAC/B,4HAAA,4BAA4B,OAAA;AAC5B,mHAAA,mBAAmB,OAAA;AACnB,uHAAA,uBAAuB,OAAA;AACvB,iHAAA,iBAAiB,OAAA;AAUnB,sEAAsE;AACtE,iFAAiF;AACjF,+BAWgB;AAVd,sGAAA,cAAc,OAAA;AACd,wGAAA,gBAAgB,OAAA;AAChB,iHAAA,yBAAyB,OAAA;AACzB,4FAAA,IAAI,OAAA;AACJ,oGAAA,YAAY,OAAA;AACZ,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,iGAAA,SAAS,OAAA;AACT,yGAAA,iBAAiB,OAAA;AACjB,uGAAA,eAAe,OAAA;AAcjB,oDAAoD;AACpD,6CAA2B;AAE3B,uFAAuF;AACvF,8CAA4B;AAE5B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAAiE;AAAxD,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAS7C,6DAO+B;AAN7B,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,yHAAA,kBAAkB,OAAA;AAClB,wHAAA,iBAAiB,OAAA;AACjB,4HAAA,qBAAqB,OAAA;AAWvB,wFAAwF;AACxF,2CAA2C;AAC3C,uCAA4C;AAAnC,sGAAA,YAAY,OAAA;AAErB,iDAA+E;AAAtE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AAGnD,8EAA8E;AAC9E,gFAAgF;AAChF,mDAS0B;AARxB,iIAAA,+BAA+B,OAAA;AAC/B,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,2HAAA,yBAAyB,OAAA;AACzB,uHAAA,qBAAqB,OAAA;AACrB,2HAAA,yBAAyB,OAAA;AACzB,+HAAA,6BAA6B,OAAA;AAC7B,mHAAA,iBAAiB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,mEAAmE;AACnE,yCAA2G;AAAlG,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,yHAAA,4BAA4B,OAAA;AACrF,2CAAyB;AACzB,mDAAiC;AACjC,8CAA4B;AAC5B,2FAA2F;AAC3F,gDAA8B;AAC9B,mDAAoE;AAA3D,sHAAA,oBAAoB,OAAA;AAAE,4GAAA,UAAU,OAAA;AAGzC,6EAA6E;AAC7E,+CAOwB;AANtB,wHAAA,wBAAwB,OAAA;AACxB,+HAAA,+BAA+B,OAAA;AAC/B,4HAAA,4BAA4B,OAAA;AAC5B,mHAAA,mBAAmB,OAAA;AACnB,uHAAA,uBAAuB,OAAA;AACvB,iHAAA,iBAAiB,OAAA;AAUnB,sEAAsE;AACtE,iFAAiF;AACjF,+BAWgB;AAVd,sGAAA,cAAc,OAAA;AACd,wGAAA,gBAAgB,OAAA;AAChB,iHAAA,yBAAyB,OAAA;AACzB,4FAAA,IAAI,OAAA;AACJ,oGAAA,YAAY,OAAA;AACZ,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,iGAAA,SAAS,OAAA;AACT,yGAAA,iBAAiB,OAAA;AACjB,uGAAA,eAAe,OAAA;AAcjB,oDAAoD;AACpD,6CAA2B;AAE3B,uFAAuF;AACvF,8CAA4B;AAE5B,0FAA0F;AAC1F,0CAAwB;AAExB,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAAiE;AAAxD,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAS7C,6DAO+B;AAN7B,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,yHAAA,kBAAkB,OAAA;AAClB,wHAAA,iBAAiB,OAAA;AACjB,4HAAA,qBAAqB,OAAA;AAWvB,wFAAwF;AACxF,2CAA2C;AAC3C,uCAA4C;AAAnC,sGAAA,YAAY,OAAA;AAErB,iDAA+E;AAAtE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AAGnD,8EAA8E;AAC9E,gFAAgF;AAChF,mDAY0B;AAXxB,iIAAA,+BAA+B,OAAA;AAC/B,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,2HAAA,yBAAyB,OAAA;AACzB,oHAAA,kBAAkB,OAAA;AAClB,qHAAA,mBAAmB,OAAA;AACnB,uHAAA,qBAAqB,OAAA;AACrB,uHAAA,qBAAqB,OAAA;AACrB,2HAAA,yBAAyB,OAAA;AACzB,+HAAA,6BAA6B,OAAA;AAC7B,mHAAA,iBAAiB,OAAA"}
@@ -0,0 +1,65 @@
1
+ import { type Jwks } from './jwks-cache';
2
+ /**
3
+ * Accepting your OLD auth provider's JWTs during a cutover — today, Better
4
+ * Auth's `jwt` plugin tokens.
5
+ *
6
+ * When you move to Atlas, API clients may still hold short-lived JWTs your
7
+ * Better Auth app minted. With `legacyIssuers` on an {@link AtlasBackend}, a
8
+ * token whose `iss` is one of these issuers is verified against THAT issuer's
9
+ * key set (the JWKS you imported into Atlas, or the old app's `/api/auth/jwks`)
10
+ * for a bounded window, and its `sub` (the Better Auth user id) is mapped to the
11
+ * Atlas user id — Atlas keeps the Better Auth id as the user's `external_id`.
12
+ * After `until`, those tokens are refused like any other foreign token.
13
+ */
14
+ export interface LegacyIssuer {
15
+ /** The old provider. Only `better_auth` today. */
16
+ kind?: 'better_auth';
17
+ /** The `iss` the old tokens carry (Better Auth: its `baseURL`, unless `jwt.issuer` was set). */
18
+ issuer: string;
19
+ /** The imported key set. Exactly one of `jwks` / `jwksUrl`. */
20
+ jwks?: Jwks;
21
+ /** Where to fetch the old key set (e.g. `https://app.example.com/api/auth/jwks`). */
22
+ jwksUrl?: string;
23
+ /** Expected `aud` (Better Auth: its `baseURL`, unless `jwt.audience` was set). Unchecked when unset. */
24
+ audience?: string | readonly string[];
25
+ /** The end of the acceptance window. Required: a legacy issuer is never accepted forever. */
26
+ until: Date | string | number;
27
+ /** Signing algorithms to accept. Default: Better Auth's (EdDSA, ES256, ES512, RS256, PS256). */
28
+ algorithms?: readonly string[];
29
+ /**
30
+ * Map the old `sub` to the Atlas user id. Default: look the user up by
31
+ * `external_id` through the Backend API (needs `secretKey` + `bapiBaseUrl`
32
+ * on the backend), cached in memory. Return null to refuse the token.
33
+ */
34
+ resolveSubject?: (legacySub: string, claims: Record<string, unknown>) => Promise<string | null> | string | null;
35
+ }
36
+ /** Better Auth's `jwt` plugin key algorithms. */
37
+ export declare const BETTER_AUTH_JWT_ALGS: string[];
38
+ export interface LegacyVerifierDeps {
39
+ issuers: readonly LegacyIssuer[];
40
+ secretKey?: string;
41
+ bapiBaseUrl?: string;
42
+ fetchImpl?: typeof fetch;
43
+ now?: () => number;
44
+ clockToleranceSeconds: number;
45
+ }
46
+ export type LegacyVerifyOutcome = {
47
+ ok: true;
48
+ claims: Record<string, unknown>;
49
+ } | {
50
+ ok: false;
51
+ reason: 'invalid' | 'no_keys';
52
+ };
53
+ /** The unverified `iss` of a compact JWT, for routing only — never trusted on its own. */
54
+ export declare function peekIssuer(token: string): string | undefined;
55
+ export declare class LegacyIssuerVerifier {
56
+ private readonly deps;
57
+ private readonly caches;
58
+ private readonly subjects;
59
+ constructor(deps: LegacyVerifierDeps);
60
+ private get now();
61
+ /** The configured entry for this `iss`, when its window is still open. */
62
+ match(iss: string | undefined): LegacyIssuer | undefined;
63
+ verify(token: string, entry: LegacyIssuer): Promise<LegacyVerifyOutcome>;
64
+ private resolve;
65
+ }
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LegacyIssuerVerifier = exports.BETTER_AUTH_JWT_ALGS = void 0;
4
+ exports.peekIssuer = peekIssuer;
5
+ const jose_1 = require("jose");
6
+ const jwks_cache_1 = require("./jwks-cache");
7
+ /** Better Auth's `jwt` plugin key algorithms. */
8
+ exports.BETTER_AUTH_JWT_ALGS = ['EdDSA', 'ES256', 'ES512', 'RS256', 'PS256'];
9
+ /** How long a resolved sub → Atlas id mapping is reused. */
10
+ const SUBJECT_TTL_MS = 5 * 60_000;
11
+ /** Cap on cached subjects, so a stream of distinct tokens can't grow memory without bound. */
12
+ const SUBJECT_CACHE_MAX = 10_000;
13
+ /** The unverified `iss` of a compact JWT, for routing only — never trusted on its own. */
14
+ function peekIssuer(token) {
15
+ try {
16
+ const iss = (0, jose_1.decodeJwt)(token).iss;
17
+ return typeof iss === 'string' ? iss : undefined;
18
+ }
19
+ catch {
20
+ return undefined;
21
+ }
22
+ }
23
+ function untilMs(until) {
24
+ const t = until instanceof Date ? until.getTime() : typeof until === 'number' ? until : Date.parse(until);
25
+ return Number.isFinite(t) ? t : 0;
26
+ }
27
+ class LegacyIssuerVerifier {
28
+ deps;
29
+ caches = new Map();
30
+ subjects = new Map();
31
+ constructor(deps) {
32
+ this.deps = deps;
33
+ for (const entry of deps.issuers) {
34
+ const hasUrl = typeof entry.jwksUrl === 'string' && entry.jwksUrl.length > 0;
35
+ if (hasUrl === (entry.jwks !== undefined)) {
36
+ throw new Error(`legacyIssuers: "${entry.issuer}" needs exactly one of \`jwks\` or \`jwksUrl\`.`);
37
+ }
38
+ if (!entry.issuer)
39
+ throw new Error('legacyIssuers: every entry needs `issuer`.');
40
+ if (!untilMs(entry.until))
41
+ throw new Error(`legacyIssuers: "${entry.issuer}" needs a valid \`until\` (the end of the window).`);
42
+ if (!entry.resolveSubject && (!deps.secretKey || !deps.bapiBaseUrl)) {
43
+ throw new Error(`legacyIssuers: "${entry.issuer}" maps its \`sub\` to an Atlas user through the Backend API, which needs \`secretKey\` and \`bapiBaseUrl\` on AtlasBackend — or give the issuer a \`resolveSubject\`.`);
44
+ }
45
+ this.caches.set(entry.issuer, new jwks_cache_1.JwksCache({
46
+ url: hasUrl ? entry.jwksUrl : undefined,
47
+ staticJwks: entry.jwks,
48
+ fetchImpl: deps.fetchImpl,
49
+ now: deps.now,
50
+ }));
51
+ }
52
+ }
53
+ get now() {
54
+ return (this.deps.now ?? Date.now)();
55
+ }
56
+ /** The configured entry for this `iss`, when its window is still open. */
57
+ match(iss) {
58
+ if (!iss)
59
+ return undefined;
60
+ const entry = this.deps.issuers.find((e) => e.issuer === iss);
61
+ if (!entry)
62
+ return undefined;
63
+ return untilMs(entry.until) > this.now ? entry : undefined;
64
+ }
65
+ async verify(token, entry) {
66
+ const cache = this.caches.get(entry.issuer);
67
+ const keys = await cache.get((0, jwks_cache_1.readKid)(token));
68
+ if (!keys || keys.keys.length === 0)
69
+ return { ok: false, reason: 'no_keys' };
70
+ let payload;
71
+ try {
72
+ const verified = await (0, jose_1.jwtVerify)(token, (0, jose_1.createLocalJWKSet)(keys), {
73
+ algorithms: [...(entry.algorithms ?? exports.BETTER_AUTH_JWT_ALGS)],
74
+ issuer: entry.issuer,
75
+ ...(entry.audience !== undefined ? { audience: entry.audience } : {}),
76
+ clockTolerance: this.deps.clockToleranceSeconds,
77
+ currentDate: this.deps.now ? new Date(this.deps.now()) : undefined,
78
+ });
79
+ payload = verified.payload;
80
+ }
81
+ catch {
82
+ return { ok: false, reason: 'invalid' };
83
+ }
84
+ // A legacy token without an expiry would outlive the window it is accepted in.
85
+ if (typeof payload.exp !== 'number')
86
+ return { ok: false, reason: 'invalid' };
87
+ const legacySub = typeof payload.sub === 'string' && payload.sub ? payload.sub : typeof payload.id === 'string' ? payload.id : '';
88
+ if (!legacySub)
89
+ return { ok: false, reason: 'invalid' };
90
+ const atlasId = await this.resolve(legacySub, payload, entry);
91
+ if (!atlasId)
92
+ return { ok: false, reason: 'invalid' };
93
+ return {
94
+ ok: true,
95
+ claims: {
96
+ ...payload,
97
+ sub: atlasId,
98
+ sid: typeof payload.sid === 'string' ? payload.sid : '',
99
+ external_id: legacySub,
100
+ legacy: { kind: entry.kind ?? 'better_auth', issuer: entry.issuer, sub: legacySub },
101
+ },
102
+ };
103
+ }
104
+ async resolve(legacySub, claims, entry) {
105
+ if (entry.resolveSubject) {
106
+ try {
107
+ return (await entry.resolveSubject(legacySub, claims)) || null;
108
+ }
109
+ catch {
110
+ return null;
111
+ }
112
+ }
113
+ const key = `${entry.issuer}\u0000${legacySub}`;
114
+ const hit = this.subjects.get(key);
115
+ if (hit && this.now - hit.at < SUBJECT_TTL_MS)
116
+ return hit.id;
117
+ let id = null;
118
+ try {
119
+ const url = new URL('/v1/users', this.deps.bapiBaseUrl);
120
+ url.searchParams.set('external_id', legacySub);
121
+ url.searchParams.set('limit', '1');
122
+ const res = await (this.deps.fetchImpl ?? fetch)(url.toString(), {
123
+ headers: { authorization: `Bearer ${this.deps.secretKey}` },
124
+ });
125
+ if (!res.ok)
126
+ return null; // not cached: a transient failure should not stick
127
+ const body = (await res.json());
128
+ id = body.data?.[0]?.id ?? null;
129
+ }
130
+ catch {
131
+ return null;
132
+ }
133
+ if (this.subjects.size >= SUBJECT_CACHE_MAX)
134
+ this.subjects.clear();
135
+ this.subjects.set(key, { id, at: this.now });
136
+ return id;
137
+ }
138
+ }
139
+ exports.LegacyIssuerVerifier = LegacyIssuerVerifier;
140
+ //# sourceMappingURL=legacy-issuers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-issuers.js","sourceRoot":"","sources":["../src/legacy-issuers.ts"],"names":[],"mappings":";;;AA4DA,gCAOC;AAnED,+BAA+D;AAC/D,6CAA6D;AAqC7D,iDAAiD;AACpC,QAAA,oBAAoB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAElF,4DAA4D;AAC5D,MAAM,cAAc,GAAG,CAAC,GAAG,MAAM,CAAC;AAClC,8FAA8F;AAC9F,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAejC,0FAA0F;AAC1F,SAAgB,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,gBAAS,EAAC,KAAK,CAAC,CAAC,GAAG,CAAC;QACjC,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAA4B;IAC3C,MAAM,CAAC,GAAG,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1G,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAa,oBAAoB;IAIF;IAHZ,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IACtC,QAAQ,GAAG,IAAI,GAAG,EAA6C,CAAC;IAEjF,YAA6B,IAAwB;QAAxB,SAAI,GAAJ,IAAI,CAAoB;QACnD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YAC7E,IAAI,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,MAAM,iDAAiD,CAAC,CAAC;YACpG,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YACjF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,MAAM,oDAAoD,CAAC,CAAC;YAChI,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,KAAK,CACb,mBAAmB,KAAK,CAAC,MAAM,uKAAuK,CACvM,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,KAAK,CAAC,MAAM,EACZ,IAAI,sBAAS,CAAC;gBACZ,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;gBACvC,UAAU,EAAE,KAAK,CAAC,IAAI;gBACtB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,GAAG,EAAE,IAAI,CAAC,GAAG;aACd,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAY,GAAG;QACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,GAAuB;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,KAAmB;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAA,oBAAO,EAAC,KAAK,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAE7E,IAAI,OAAgC,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAA,gBAAS,EAAC,KAAK,EAAE,IAAA,wBAAiB,EAAC,IAAa,CAAC,EAAE;gBACxE,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,4BAAoB,CAAC,CAAC;gBAC3D,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1F,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB;gBAC/C,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;aACnE,CAAC,CAAC;YACH,OAAO,GAAG,QAAQ,CAAC,OAAkC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC1C,CAAC;QACD,+EAA+E;QAC/E,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAE7E,MAAM,SAAS,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClI,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAEtD,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE;gBACN,GAAG,OAAO;gBACV,GAAG,EAAE,OAAO;gBACZ,GAAG,EAAE,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBACvD,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;aACpF;SACF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,MAA+B,EAAE,KAAmB;QAC3F,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,MAAM,SAAS,SAAS,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,GAAG,cAAc;YAAE,OAAO,GAAG,CAAC,EAAE,CAAC;QAE7D,IAAI,EAAE,GAAkB,IAAI,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAY,CAAC,CAAC;YACzD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;YAC/C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;gBAC/D,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,SAAU,EAAE,EAAE;aAC7D,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC,CAAC,mDAAmD;YAC7E,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsC,CAAC;YACrE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,iBAAiB;YAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7C,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AA7GD,oDA6GC"}