@atlasauth/backend 0.7.3 → 0.9.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 (52) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +175 -1
  3. package/dist/client/activity.d.ts +5 -0
  4. package/dist/client/activity.js.map +1 -1
  5. package/dist/client/branding.d.ts +58 -0
  6. package/dist/client/branding.js.map +1 -1
  7. package/dist/client/domains.d.ts +13 -0
  8. package/dist/client/domains.js.map +1 -1
  9. package/dist/client/email-templates.d.ts +1 -1
  10. package/dist/client/email-templates.js.map +1 -1
  11. package/dist/client/index.d.ts +55 -2
  12. package/dist/client/index.js +4 -0
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/client/instance.d.ts +201 -0
  15. package/dist/client/instance.js +38 -0
  16. package/dist/client/instance.js.map +1 -1
  17. package/dist/client/logout-notify-endpoints.d.ts +71 -0
  18. package/dist/client/logout-notify-endpoints.js +34 -0
  19. package/dist/client/logout-notify-endpoints.js.map +1 -0
  20. package/dist/client/messaging.d.ts +168 -0
  21. package/dist/client/messaging.js +45 -0
  22. package/dist/client/messaging.js.map +1 -1
  23. package/dist/client/oauth-clients.d.ts +86 -1
  24. package/dist/client/oauth-clients.js +23 -2
  25. package/dist/client/oauth-clients.js.map +1 -1
  26. package/dist/client/platform.d.ts +129 -0
  27. package/dist/client/platform.js +80 -0
  28. package/dist/client/platform.js.map +1 -1
  29. package/dist/client/users.d.ts +29 -1
  30. package/dist/client/users.js +10 -2
  31. package/dist/client/users.js.map +1 -1
  32. package/dist/client/webhooks.d.ts +21 -0
  33. package/dist/client/webhooks.js.map +1 -1
  34. package/dist/index.d.ts +4 -2
  35. package/dist/index.js +15 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/logout-token.d.ts +8 -0
  38. package/dist/logout-token.js +20 -15
  39. package/dist/logout-token.js.map +1 -1
  40. package/dist/oidc.d.ts +225 -0
  41. package/dist/oidc.js +631 -0
  42. package/dist/oidc.js.map +1 -0
  43. package/dist/testing.d.ts +90 -1
  44. package/dist/testing.js +202 -3
  45. package/dist/testing.js.map +1 -1
  46. package/dist/verify.d.ts +21 -0
  47. package/dist/verify.js +20 -0
  48. package/dist/verify.js.map +1 -1
  49. package/dist/webhooks.d.ts +16 -5
  50. package/dist/webhooks.js +11 -7
  51. package/dist/webhooks.js.map +1 -1
  52. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @atlasauth/backend changelog
2
2
 
3
+ ## 0.9.0
4
+ - **OIDC relying party.** New `oidc` namespace and standalone functions for the hosted-redirect sign-in: `oidcStart` (`oidc.start`), `oidcCallback` (`oidc.callback`), `oidcLogoutUrl` (`oidc.logoutUrl`), `oidcVerifyIdToken` (`oidc.verifyIdToken`), `oidcClearCookie` (`oidc.clearCookie`). `start({ issuer, clientId, redirectUri, scope?, prompt?, loginHint?, audienceHint?, extraParams?, cookieName?, secret? })` returns `{ url, cookie, state, nonce }`: a PKCE (S256) authorize URL from discovery and a `Set-Cookie` for a 10-minute, httpOnly, `SameSite=Lax`, callback-path flow cookie, AES-GCM sealed when `secret` is set. `callback({ …, clientSecret?, clientAuth?: 'client_secret_basic' | 'client_secret_post' | 'none', query, cookie, secret?, clockToleranceSec? })` returns `OidcIdentity` (`sub`, `namespacedSub` = `${issuer}#${sub}`, `email`, `emailVerified`, `name`, `idToken`, `accessToken`, `refreshToken?`, `expiresAt` in epoch ms, `claims`, `clearCookie`). The ID token is verified with RS256 pinned, exact `iss`, `aud` containing the client id (and `azp` when present or when there are several audiences), `nonce`, `exp`/`iat` with tolerance, and `at_hash`. Discovery is cached per issuer for an hour.
5
+ - **Errors.** `AtlasOidcError` with `code` (`AtlasOidcErrorCode`: `state_mismatch`, `issuer_mismatch`, `invalid_request`, `invalid_token`, `token_exchange_failed`, `access_denied`, `discovery_failed`), `oauthError`, `description`, `status`, `clearCookie` and `cause`.
6
+ - **`AtlasBackend#oidc`.** The same helpers with the backend's `issuer`, `fetchImpl` and `now` filled in (`AtlasBackendOidc`).
7
+ - **Test issuer.** `createTestIssuer` accepts `clientId`, `clientSecret` and `idTokenTtlSeconds`, and the returned `TestIssuer` gains `clientId`, `mintIdToken(claims?, { aud?, nonce?, accessToken?, ttlSeconds?, tamper? })`, `authorize(authorizeUrl, { sub?, claims?, tamper?, error? })`, `fetch` (an offline discovery, JWKS and token endpoint) and `endpoints`. `mintSession(claims?, { tamper? })` accepts a tamper too. `TestTokenTamper` is `wrong_aud`, `wrong_iss`, `foreign_key`, `expired`, `wrong_nonce` or `alg_none`; `TEST_TOKEN_TAMPERS` lists all six. New types: `MintIdTokenOptions`, `TestAuthorizeOptions`, `TestAuthorizeResult`.
8
+ - **OAuth client secret rotation with overlap.** `oauthClients.rotateSecret(id, { overlap_seconds? }, idempotencyKey?)` takes how long the previous secret keeps working: default 86400 (24 hours), `0` revokes it now, at most 604800 (7 days). It returns `OAuthClientSecretRotation` (`client_secret`, `overlap_seconds`, `previous_secret_expires_at`: epoch ms, or null when the old secret already stopped working). New type `RotateOAuthClientSecretBody`. `OAuthClient` gains optional `previous_secret_expires_at`.
9
+ - **Issuer and verification endpoints.** `Instance` (`instance.get()`) and the platform client's `PlatformApp` gain `issuer`, `discovery_url` and `jwks_uri`; `PlatformApp` also gains `frontend_api_host`. They change when a custom domain goes active, so read them rather than hard-coding them.
10
+ - **Email verification.** `EmailAddress` gains optional `verification` (`{ status: 'verified' | 'unverified', strategy?: string | null }`). `verified` and `email_verified` are now true only for a proven address: one that signed up while `requireEmailVerification` was false reads `verified: false`, with `verification.strategy: 'skipped'`. Do not grant access on an unverified address.
11
+ - **Email templates.** `EmailTemplateName` adds `account_secured` (variable `when`): sent when the owner of an address proves it and the account is secured from whoever had set it up without proof.
12
+ - **Managed email uses your own provider account.** `messaging.managedEmail.create` now sets the domain up on YOUR Resend or Brevo account: `CreateManagedEmailBody` gains `transport` (`resend` | `brevo`) + `config.api_key`, or `provider_id`. `ManagedEmail` gains `backend`, `provider_id` and `feedback_webhook`; `limits` is now always `null` and `reputation` is `your_provider_account`. `DeletedManagedEmail` gains `provider_removed`. `ManagedEmailRecord.purpose` adds `ownership` and `dmarc`.
13
+ - **Development email sender.** New `messaging.developmentEmail.get / enable / disable` (`DevelopmentEmail`, `EnableDevelopmentEmailBody`): your own email provider in development mode, for a development instance without a verified domain. `MessagingProviders` gains `development_email`.
14
+ - **Provider mode.** Email provider bodies accept `mode` (`standard` | `development`); provider responses gain optional `id` and `mode` (`standard` | `development` | `managed_domain`).
15
+ - **Compatible** except `ManagedEmail.limits` (was `{ hourly, daily }`, now `null`) and `ManagedEmail.reputation` (new constant). Everything else is new exports, optional parameters and fields; `rotateSecret(id)` behaves as before.
16
+
17
+ ## 0.8.0
18
+ - **Back-channel logout, retryable failures.** A failed `LogoutTokenResult` gains `retryable: boolean`. It is `true` for `no_keys` (the issuer's keys could not be fetched: a network error, a JWKS outage, or a just-rotated key whose refetch failed) and `false` for `malformed`, `invalid` and `replayed`. Answer `503` with `Retry-After` when it is true, so Atlas retries the delivery, and `400` otherwise. The README example does this.
19
+ - **Back-channel delivery log and test.** `oauthClients.listBackchannelDeliveries(id, { limit?, starting_after? })` returns `BackchannelLogoutDeliveryPage` (`BackchannelLogoutDelivery`: `status`, `http_status`, `latency_ms`, `attempt_number`, `error`, `location`, `test`, timestamps). `oauthClients.testBackchannelLogout(id)` returns `BackchannelLogoutTest` (`ok`, `status`, `latency_ms`, `error`, `location`, `blocked_reason`, `body_excerpt`, `sid`, `delivery_id`). The platform client's `atlasIdApps` gains the same two methods plus `preflight(id)` (`AtlasIdAppPreflight`).
20
+ - **Webhooks.** `verifyWebhook` returns `deliveryId` (the signed `atlas-id` header, the same on every retry of one event: deduplicate on it) and `timestamp` (the signed `atlas-timestamp`, epoch ms) on a verified delivery. `WebhookVerifyResult` gains both, optional.
21
+ - **Users.** `User` gains optional `version`: it strictly increases with every change to the user, and user webhook payloads carry the same value. Apply an update only if its version is newer.
22
+ - **Branding.** `ResolvedBranding` (`resolved` on `branding.get` / `branding.update`) gains every writable field under its input name (`theme`, `layout`, `fontFamily`, `legal`, `copy`, `providers`, `card`, `interaction`, `socialButtons`, …) plus the derived `fontStack`, `providerOrder`, `providerHidden`, `eyebrow`, `headline`, `subheadline`, `footer`. `Branding.copy` accepts `eyebrow`.
23
+ - **Domain moves.** `instance.moveOrigin({ from, to, dry_run? })` rewrites every URL on one origin to another across the instance, its OAuth clients, webhooks, redirect URLs and Sign in with Atlas apps, and returns `OriginMove` (`changes` before → after, `problems`, `applied`); the platform client's `atlasIdApps.moveOrigin(id, body)` does the same for one app.
24
+ - **Connections and integrations.** `instance.connections()` returns `InstanceConnections` (one `InstanceConnection` row per link to another platform, with `ok`, `severity`, `fix_hint`). `instance.integrations.chatly` and `instance.integrations.forumulate` get, set and delete the built-in connections (`ChatlyIntegration`, `ForumulateIntegration`).
25
+ - **Logout fan-out.** New `logoutNotifyEndpoints` namespace: `list`, `create`, `get`, `update`, `delete` and `listDeliveries` for services that receive the same `logout_token` as your OIDC apps (`LogoutNotifyEndpoint`, `LogoutNotifyDelivery`).
26
+ - **Managed email.** `messaging.managedEmail.get / create / verify / delete({ force? })` sends from your own domain through Atlas's email account (`ManagedEmail`, `ManagedEmailRecord`, `CreateManagedEmailBody` with optional write-only `dns`). `MessagingProviders` gains `managed_email`.
27
+ - **Sign in with Atlas apps.** `atlasIdApps.findUsers(id, email)` (privacy-request lookup, `AtlasIdAppUser`), `revokeGrant(id, grantId)` (`AtlasIdGrantRevocation`) and `rotateWebhookSecret(id)`. `AtlasIdApp` gains `webhook_url`, `webhook_events` and `webhook_active`; `AtlasIdAppWithSecret` gains `webhook_secret`; `UpdateAtlasIdAppBody` accepts `webhook_url`.
28
+ - **Publisher.** New platform namespace `atlasIdPublisher`: `get`, `set`, `update({ skip_consent })`, `delete`, `verify` (`AtlasIdPublisher`). The platform client's `configChangelog.list(params)` reads the account's config history.
29
+ - **More fields.** `CookieConsent` gains `culture` and `declared_cookies` (`DeclaredCookie`); `SetCookieConsentBody` accepts `culture`. `PreflightReport` gains `sdk_versions_seen` (`SdkVersionSeen`, `SdkAdvisory`). `WebhookDelivery` gains `error` and `location`; `WebhookEndpointList` gains `event_catalog` (`WebhookEventCatalogEntry`) and `event_audiences`. `CustomDomain` gains `dns`, and `domains.create` accepts `dns` (`CustomDomainDnsInput`). `ConfigChangelogEntry` gains `target`. `users.revokeSessions(id, { revoke_grants })` also revokes OAuth grants and returns `grants_revoked`.
30
+ - **Compatible.** New methods, types and optional fields only (`retryable` is a new field on the failure branch); no signatures changed.
31
+
3
32
  ## 0.7.3
4
33
  - **Added** error code constants `CAPTCHA_KEYS_REQUIRED` (422: captcha can only be turned on once its own site key and secret are stored) and `CAPTCHA_IN_USE` (409: removing a key a live captcha flow uses; `meta.flows`).
5
34
 
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  Server-side Atlas for Node, Deno, Bun and edge runtimes. It does three things:
4
4
 
5
5
  - verifies Atlas session tokens, webhooks and back-channel logout tokens
6
+ - runs the server side of a hosted-redirect (OpenID Connect) sign-in
6
7
  - gives you a typed client for the Backend API, using your secret key (`sk_...`)
7
8
  - gives you a typed client for the Platform API, using your platform key (`psk_...`)
8
9
 
@@ -24,6 +25,150 @@ if (result.ok) console.log(result.claims.sub);
24
25
 
25
26
  The JWKS is found from the issuer and cached. Instances on the shared host also pass `instanceId` (or `publishableKey`).
26
27
 
28
+ ## Sign in with a redirect (OpenID Connect)
29
+
30
+ `oidc` runs the relying-party side of the hosted-redirect integration: state, nonce and PKCE, the flow cookie, the code exchange and the ID-token checks (RS256 only, `iss`, `aud` = your client id, `nonce`, `exp`).
31
+
32
+ ```ts
33
+ import { oidc, AtlasOidcError } from '@atlasauth/backend';
34
+
35
+ const config = {
36
+ issuer: 'https://bright-fox-42-fapi.atlasauth.net', // https:// + frontend_api_host
37
+ clientId: process.env.ATLAS_CLIENT_ID!,
38
+ redirectUri: 'https://app.example.com/auth/callback',
39
+ secret: process.env.OIDC_COOKIE_SECRET!, // 32+ random characters; seals the flow cookie
40
+ };
41
+
42
+ // Start: set the flow cookie, redirect.
43
+ const { url, cookie } = await oidc.start({ ...config, scope: 'openid profile email' });
44
+
45
+ // Callback: one call does every check.
46
+ const identity = await oidc.callback({
47
+ ...config,
48
+ clientSecret: process.env.ATLAS_CLIENT_SECRET!,
49
+ query: request.url, // or URLSearchParams, or req.query
50
+ cookie: request.headers.get('cookie'),
51
+ });
52
+ // identity: { sub, namespacedSub, email, emailVerified, name, idToken, accessToken, refreshToken?, expiresAt, claims, clearCookie }
53
+
54
+ // Sign out: end your session, then end the Atlas one.
55
+ const logout = await oidc.logoutUrl({ ...config, postLogoutRedirectUri: 'https://app.example.com/', idTokenHint });
56
+ ```
57
+
58
+ - The flow cookie is `httpOnly`, `SameSite=Lax`, `Secure` (except on a `http://localhost` callback), scoped to the callback path, and lasts 10 minutes. With `secret` it is encrypted (AES-GCM), so it can't be read or forged. Without `secret` it is only encoded. Always pass one in production.
59
+ - `namespacedSub` is `${issuer}#${sub}`. Key users on it if you accept more than one instance, so two instances' users never collide.
60
+ - `clientAuth` is `client_secret_basic` (default with a secret), `client_secret_post`, or `none` (public client, PKCE only).
61
+ - `new AtlasBackend({ issuer }).oidc` has the same methods with `issuer` filled in.
62
+ - Did your own code exchange? `oidc.verifyIdToken(idToken, { issuer, clientId, nonce })` runs just the token checks.
63
+
64
+ Failures throw `AtlasOidcError` with a stable `code`:
65
+
66
+ | `code` | Meaning |
67
+ |---|---|
68
+ | `state_mismatch` | No flow cookie, a different `state`, a cookie from another sign-in or secret, or a flow older than 10 minutes. Start again. |
69
+ | `access_denied` | Atlas redirected back with an OAuth `error`. The exact value is in `oauthError` (`access_denied`, `login_required`, …). |
70
+ | `issuer_mismatch` | The callback's `iss` parameter names a different server. |
71
+ | `invalid_request` | The callback has no `code`. |
72
+ | `token_exchange_failed` | The token endpoint refused the code or client (`oauthError`, `status`). |
73
+ | `invalid_token` | The ID token failed a check: algorithm, signature, `iss`, `aud`/`azp`, `nonce`, `exp`/`iat` or `at_hash`. |
74
+ | `discovery_failed` | The discovery document or the signing keys could not be fetched or don't match the issuer. |
75
+
76
+ Every error from `callback` carries `clearCookie`: send it with your error page too.
77
+
78
+ ### Next.js (App Router)
79
+
80
+ ```ts
81
+ // app/auth/login/route.ts
82
+ import { oidc } from '@atlasauth/backend';
83
+ import { config } from '@/lib/atlas';
84
+
85
+ export async function GET() {
86
+ const { url, cookie } = await oidc.start(config);
87
+ return new Response(null, { status: 302, headers: { location: url, 'set-cookie': cookie } });
88
+ }
89
+
90
+ // app/auth/callback/route.ts
91
+ import { oidc, AtlasOidcError } from '@atlasauth/backend';
92
+ import { config } from '@/lib/atlas';
93
+
94
+ export async function GET(request: Request) {
95
+ try {
96
+ const user = await oidc.callback({
97
+ ...config,
98
+ clientSecret: process.env.ATLAS_CLIENT_SECRET!,
99
+ query: request.url,
100
+ cookie: request.headers.get('cookie'),
101
+ });
102
+ const headers = new Headers({ location: '/' });
103
+ headers.append('set-cookie', user.clearCookie);
104
+ headers.append('set-cookie', await createAppSession(user)); // your own session cookie
105
+ return new Response(null, { status: 302, headers });
106
+ } catch (error) {
107
+ if (!(error instanceof AtlasOidcError)) throw error;
108
+ return new Response(`Sign-in failed (${error.code})`, {
109
+ status: 400,
110
+ headers: error.clearCookie ? { 'set-cookie': error.clearCookie } : {},
111
+ });
112
+ }
113
+ }
114
+ ```
115
+
116
+ ### Express
117
+
118
+ ```ts
119
+ import express from 'express';
120
+ import { oidc, AtlasOidcError } from '@atlasauth/backend';
121
+
122
+ const app = express();
123
+
124
+ app.get('/auth/login', async (req, res) => {
125
+ const { url, cookie } = await oidc.start(config);
126
+ res.append('Set-Cookie', cookie).redirect(url);
127
+ });
128
+
129
+ app.get('/auth/callback', async (req, res) => {
130
+ try {
131
+ const user = await oidc.callback({
132
+ ...config,
133
+ clientSecret: process.env.ATLAS_CLIENT_SECRET!,
134
+ query: req.originalUrl,
135
+ cookie: req.headers.cookie,
136
+ });
137
+ res.append('Set-Cookie', user.clearCookie);
138
+ await startYourSession(req, res, user.namespacedSub);
139
+ res.redirect('/');
140
+ } catch (error) {
141
+ if (!(error instanceof AtlasOidcError)) throw error;
142
+ if (error.clearCookie) res.append('Set-Cookie', error.clearCookie);
143
+ res.status(400).send(`Sign-in failed (${error.code})`);
144
+ }
145
+ });
146
+ ```
147
+
148
+ ## Test offline
149
+
150
+ `createTestIssuer()` mints session tokens and ID tokens with a throwaway key, and its `fetch` serves discovery, the JWKS and a token endpoint, so a full redirect sign-in runs in a unit test with no network.
151
+
152
+ ```ts
153
+ import { createTestIssuer, oidc, TEST_TOKEN_TAMPERS } from '@atlasauth/backend';
154
+
155
+ const fx = await createTestIssuer({ clientSecret: 'test-secret' });
156
+ const config = { issuer: fx.issuer, clientId: fx.clientId, redirectUri: 'https://app.example.com/auth/callback', secret: '…32+ chars…', fetchImpl: fx.fetch };
157
+
158
+ const { url, cookie } = await oidc.start(config);
159
+ const { callbackUrl } = await fx.authorize(url, { sub: 'user_1', claims: { email: 'a@example.com', email_verified: true } });
160
+ const user = await oidc.callback({ ...config, clientSecret: 'test-secret', query: callbackUrl, cookie });
161
+
162
+ // Negative cases: wrong_aud, wrong_iss, foreign_key, expired, wrong_nonce, alg_none.
163
+ for (const tamper of TEST_TOKEN_TAMPERS) {
164
+ const { url, cookie } = await oidc.start(config);
165
+ const { callbackUrl } = await fx.authorize(url, { tamper });
166
+ await expect(oidc.callback({ ...config, clientSecret: 'test-secret', query: callbackUrl, cookie })).rejects.toMatchObject({ code: 'invalid_token' });
167
+ }
168
+ ```
169
+
170
+ `fx.mintIdToken(claims, { aud, nonce, tamper })` and `fx.mintSession(claims, { tamper })` mint single tokens. `@atlasauth/testing` re-exports `createTestIssuer`.
171
+
27
172
  ## Management client (secret key)
28
173
 
29
174
  ```ts
@@ -178,6 +323,25 @@ The platform client has these namespaces:
178
323
 
179
324
  It accepts the same `strict`, `onUnknownFields` and `withOptions` settings.
180
325
 
326
+ ### Domain moves, logout fan-out and managed email
327
+
328
+ ```ts
329
+ // Move every URL from the old origin to the new one. dry_run first shows the diff.
330
+ const preview = await atlas.instance.moveOrigin({ from: 'https://old.example.com', to: 'https://example.com', dry_run: true });
331
+ for (const c of preview.changes) console.log(c.object, c.field, c.before, '->', c.after);
332
+
333
+ // Send the same logout_token your OIDC apps get to another service.
334
+ await atlas.logoutNotifyEndpoints.create({ url: 'https://api.example.com/atlas/logout' });
335
+
336
+ // Send email from your own domain through Atlas, then publish the returned DNS records.
337
+ const managed = await atlas.messaging.managedEmail.create({ from_address: 'Acme <no-reply@example.com>' });
338
+ console.log(managed.records);
339
+ ```
340
+
341
+ On the platform client, `atlasIdApps.findUsers(id, email)` answers a privacy request for one app,
342
+ `atlasIdApps.revokeGrant(id, grantId)` revokes one person's approval, and `atlasIdPublisher` claims and verifies
343
+ the publisher name shown on consent screens.
344
+
181
345
  ## Back-channel logout
182
346
 
183
347
  When a user signs out of Atlas, Atlas POSTs a `logout_token` to your `backchannel_logout_uri`. Verify it before you end the matching local sessions:
@@ -198,7 +362,13 @@ export async function handleBackchannelLogout(form: URLSearchParams) {
198
362
  if (!token) return { status: 400, headers };
199
363
 
200
364
  const result = await logoutTokens.verify(token);
201
- if (!result.ok) return { status: 400, headers };
365
+ if (!result.ok) {
366
+ // retryable: our side failed for now (the issuer's keys could not be fetched).
367
+ // 503 + Retry-After makes Atlas send it again; 400 is final and never retried.
368
+ return result.retryable
369
+ ? { status: 503, headers: { ...headers, 'Retry-After': '30' } }
370
+ : { status: 400, headers };
371
+ }
202
372
 
203
373
  const { sid, sub } = result.claims;
204
374
  if (sid) await sessions.deleteByAtlasSid(sid); // your session store
@@ -222,6 +392,10 @@ For tokens signed by your own instance, `new AtlasBackend({ issuer }).verifyLogo
222
392
 
223
393
  To refuse replays across several servers, implement `LogoutReplayStore.remember(jti, expiresAtMs)` on a shared store, for example Redis `SET NX PX`.
224
394
 
395
+ Atlas retries a delivery that gets a `5xx`, `408`, `429` or no answer, after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours and 10 hours. Any other `4xx` is final. Atlas never follows a redirect: a `3xx` answer is recorded as `backchannel_redirect_not_followed`, so after a domain move update `backchannel_logout_uri` to the final URL. Answer your own transient failures (a database that is down) with `503` too.
396
+
397
+ To check the route end to end, `oauthClients.testBackchannelLogout(id)` sends a signed test token (`sid` starting `sid_test_`, extra claim `atlas_test: true`) and returns what your route answered; `oauthClients.listBackchannelDeliveries(id)` lists every attempt.
398
+
225
399
  ## Webhooks
226
400
 
227
401
  `verifyWebhook` checks the signature on events Atlas sends to your webhook endpoints. You manage endpoints with `atlas.webhooks.endpoints`: create, update, reveal or rotate a secret, send a test event, and redeliver a past delivery.
@@ -70,6 +70,11 @@ export interface ConfigChangelogEntry {
70
70
  };
71
71
  action: string;
72
72
  ip?: string | null;
73
+ /** The object that changed, e.g. `{ type: 'oauth_client', id }`. */
74
+ target?: {
75
+ type: string;
76
+ id: string | null;
77
+ } | null;
73
78
  changes?: Array<{
74
79
  section: string;
75
80
  before: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/client/activity.ts"],"names":[],"mappings":";;AA4EA,wCAOC;AAED,sCAOC;AAED,0DAaC;AA/BD,SAAgB,cAAc,CAAC,OAAkB;IAC/C,OAAO;QACL,2EAA2E;QAC3E,IAAI,CAAC,SAAmC,EAAE;YACxC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9E,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,aAAa,CAAC,OAAkB;IAC9C,OAAO;QACL,0FAA0F;QAC1F,GAAG,CAAC,SAA4B,EAAE;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,uBAAuB,CAAC,OAAkB;IACxD,OAAO;QACL,IAAI,CACF,SAAoC,EAAE;YAOtC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/client/activity.ts"],"names":[],"mappings":";;AA8EA,wCAOC;AAED,sCAOC;AAED,0DAaC;AA/BD,SAAgB,cAAc,CAAC,OAAkB;IAC/C,OAAO;QACL,2EAA2E;QAC3E,IAAI,CAAC,SAAmC,EAAE;YACxC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9E,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,aAAa,CAAC,OAAkB;IAC9C,OAAO;QACL,0FAA0F;QAC1F,GAAG,CAAC,SAA4B,EAAE;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,uBAAuB,CAAC,OAAkB;IACxD,OAAO;QACL,IAAI,CACF,SAAoC,EAAE;YAOtC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -32,6 +32,7 @@ export interface Branding {
32
32
  hidden?: string[];
33
33
  };
34
34
  copy?: {
35
+ eyebrow?: string;
35
36
  headline?: string;
36
37
  subheadline?: string;
37
38
  footer?: string;
@@ -116,6 +117,63 @@ export interface ResolvedBranding {
116
117
  colorBackground: string;
117
118
  colorText: string;
118
119
  supportEmail: string | null;
120
+ colorAccent?: string;
121
+ colorCard?: string;
122
+ colorBorder?: string;
123
+ borderRadius?: string;
124
+ theme?: 'light' | 'dark' | 'auto';
125
+ /** The font stack name in force (`system` when unset or unknown). */
126
+ fontFamily?: string;
127
+ /** The CSS font-family list `fontFamily` resolves to. */
128
+ fontStack?: string;
129
+ fontUrl?: string | null;
130
+ layout?: 'centered' | 'split' | 'wall';
131
+ background?: Record<string, unknown>;
132
+ providers?: {
133
+ order: string[];
134
+ hidden: string[];
135
+ };
136
+ providerOrder?: string[];
137
+ providerHidden?: string[];
138
+ socialButtons?: Record<string, unknown>;
139
+ codeInput?: 'boxes' | 'single';
140
+ card?: {
141
+ width: string;
142
+ align: string;
143
+ logoSize: string;
144
+ };
145
+ typography?: {
146
+ headingSize: string;
147
+ headingWeight: string;
148
+ };
149
+ buttonShape?: string;
150
+ cardBorder?: string;
151
+ inputSize?: string;
152
+ interaction?: Record<string, unknown>;
153
+ backgroundPattern?: string;
154
+ cardStyle?: string;
155
+ textScale?: string;
156
+ socialPlacement?: 'top' | 'bottom';
157
+ sectionOrder?: string[];
158
+ legal?: {
159
+ termsUrl: string | null;
160
+ privacyUrl: string | null;
161
+ required: boolean;
162
+ };
163
+ signUpFields?: Array<Record<string, unknown>>;
164
+ copy?: {
165
+ eyebrow: string | null;
166
+ headline: string | null;
167
+ subheadline: string | null;
168
+ footer: string | null;
169
+ };
170
+ eyebrow?: string | null;
171
+ headline?: string | null;
172
+ subheadline?: string | null;
173
+ footer?: string | null;
174
+ customCss?: string;
175
+ customHtmlHeader?: string;
176
+ customHtmlFooter?: string;
119
177
  }
120
178
  /**
121
179
  * A read/update echoes the stored branding plus `resolved` — the sanitized shape
@@ -1 +1 @@
1
- {"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/client/branding.ts"],"names":[],"mappings":";;AAyIA,4CAcC;AAdD,SAAgB,gBAAgB,CAAC,OAAkB;IACjD,OAAO;QACL,GAAG;YACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,kEAAkE;QAClE,MAAM,CAAC,IAAuB;YAC5B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,0EAA0E;QAC1E,OAAO,CAAC,IAAuB;YAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/client/branding.ts"],"names":[],"mappings":";;AAkLA,4CAcC;AAdD,SAAgB,gBAAgB,CAAC,OAAkB;IACjD,OAAO;QACL,GAAG;YACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,kEAAkE;QAClE,MAAM,CAAC,IAAuB;YAC5B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,0EAA0E;QAC1E,OAAO,CAAC,IAAuB;YAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -13,6 +13,18 @@ export interface CustomDomain {
13
13
  failure_reason: string | null;
14
14
  certificate_expires_at: number | null;
15
15
  cookie_domain: string | null;
16
+ /** DNS automation: the provider Atlas writes this host's record with (the token is never returned). */
17
+ dns?: {
18
+ provider: 'cloudflare';
19
+ token_set: boolean;
20
+ } | null;
21
+ }
22
+ /** Let Atlas write the domain's DNS record. The token is write-only. */
23
+ export interface CustomDomainDnsInput {
24
+ provider: 'cloudflare';
25
+ api_token: string;
26
+ /** Replace a conflicting existing record. */
27
+ overwrite?: boolean;
16
28
  }
17
29
  export interface ListDomainsResponse {
18
30
  object: 'list';
@@ -31,6 +43,7 @@ export declare function domainsResource(request: RequestFn): {
31
43
  create(body: {
32
44
  host: string;
33
45
  role?: "fapi" | "accounts";
46
+ dns?: CustomDomainDnsInput;
34
47
  }, idempotencyKey?: string): Promise<CustomDomain & {
35
48
  instructions: Record<string, unknown>;
36
49
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/client/domains.ts"],"names":[],"mappings":";;AA4BA,0CAkBC;AA9CD,uCAAgD;AA4BhD,SAAgB,eAAe,CAAC,OAAkB;IAChD,OAAO;QACL,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,CACJ,IAAkD,EAClD,cAAuB;YAEvB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/client/domains.ts"],"names":[],"mappings":";;AAsCA,0CAkBC;AAxDD,uCAAgD;AAsChD,SAAgB,eAAe,CAAC,OAAkB;IAChD,OAAO;QACL,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,CACJ,IAA8E,EAC9E,cAAuB;YAEvB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { type RequestFn } from './request';
2
2
  import type { ListPage } from './types';
3
3
  /** The transactional email a template drives. */
4
- export type EmailTemplateName = 'verification_code' | 'magic_link' | 'password_reset' | 'password_changed' | 'account_exists_notice' | 'organization_invitation' | 'new_device_sign_in' | 'session_revoked_token_reuse' | 'account_locked' | 'team_member_added' | 'team_role_changed';
4
+ export type EmailTemplateName = 'verification_code' | 'magic_link' | 'password_reset' | 'password_changed' | 'account_exists_notice' | 'organization_invitation' | 'new_device_sign_in' | 'session_revoked_token_reuse' | 'account_locked' | 'account_secured' | 'team_member_added' | 'team_role_changed';
5
5
  /** The customizable body of a template: a subject line and a text body. */
6
6
  export interface EmailTemplateBody {
7
7
  subject?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"email-templates.js","sourceRoot":"","sources":["../../src/client/email-templates.ts"],"names":[],"mappings":";;AAwDA,wDAkBC;AA1ED,uCAAgD;AAwDhD,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,2EAA2E;QAC3E,OAAO,CAAC,IAAY,EAAE,OAA0B,EAAE;YAChD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD,2DAA2D;QAC3D,MAAM,CAAC,IAAY,EAAE,IAAuB;YAC1C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,8BAA8B;QAC9B,MAAM,CAAC,IAAY;YACjB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"email-templates.js","sourceRoot":"","sources":["../../src/client/email-templates.ts"],"names":[],"mappings":";;AAyDA,wDAkBC;AA3ED,uCAAgD;AAyDhD,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,2EAA2E;QAC3E,OAAO,CAAC,IAAY,EAAE,OAA0B,EAAE;YAChD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD,2DAA2D;QAC3D,MAAM,CAAC,IAAY,EAAE,IAAuB;YAC1C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,8BAA8B;QAC9B,MAAM,CAAC,IAAY;YACjB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -35,10 +35,13 @@ declare function buildNamespaces(request: RequestFn): {
35
35
  deleted: true;
36
36
  }>;
37
37
  listSessions(id: string): Promise<import("./types").ListPage<import("./users").UserSession>>;
38
- revokeSessions(id: string): Promise<{
38
+ revokeSessions(id: string, options?: {
39
+ revoke_grants?: boolean;
40
+ }): Promise<{
39
41
  object: "user";
40
42
  id: string;
41
43
  sessions_revoked: number;
44
+ grants_revoked?: number;
42
45
  }>;
43
46
  addEmail(id: string, body: {
44
47
  email_address: string;
@@ -338,13 +341,15 @@ declare function buildNamespaces(request: RequestFn): {
338
341
  get(id: string): Promise<import("./oauth-clients").OAuthClient>;
339
342
  create(body: import("./oauth-clients").CreateOAuthClientBody, idempotencyKey?: string): Promise<import("./oauth-clients").OAuthClientWithSecret>;
340
343
  update(id: string, body: import("./oauth-clients").UpdateOAuthClientBody): Promise<import("./oauth-clients").OAuthClient>;
341
- rotateSecret(id: string): Promise<import("./oauth-clients").OAuthClientWithSecret>;
344
+ rotateSecret(id: string, body?: import("./oauth-clients").RotateOAuthClientSecretBody, idempotencyKey?: string): Promise<import("./oauth-clients").OAuthClientSecretRotation>;
342
345
  delete(id: string): Promise<{
343
346
  object: "oauth_client";
344
347
  id: string;
345
348
  deleted: true;
346
349
  note: string;
347
350
  }>;
351
+ listBackchannelDeliveries(id: string, query?: import("./oauth-clients").BackchannelDeliveriesQuery): Promise<import("./oauth-clients").BackchannelLogoutDeliveryPage>;
352
+ testBackchannelLogout(id: string): Promise<import("./oauth-clients").BackchannelLogoutTest>;
348
353
  grants: {
349
354
  list(clientId: string): Promise<import("./types").ListPage<import("./oauth-clients").ClientGrant>>;
350
355
  create(clientId: string, body: {
@@ -396,6 +401,7 @@ declare function buildNamespaces(request: RequestFn): {
396
401
  create(body: {
397
402
  host: string;
398
403
  role?: "fapi" | "accounts";
404
+ dns?: import("./domains").CustomDomainDnsInput;
399
405
  }, idempotencyKey?: string): Promise<import("./domains").CustomDomain & {
400
406
  instructions: Record<string, unknown>;
401
407
  }>;
@@ -835,6 +841,24 @@ declare function buildNamespaces(request: RequestFn): {
835
841
  deleteChannel(channel: "email" | "sms", options?: {
836
842
  force?: boolean;
837
843
  }): Promise<import("./messaging").DeletedMessagingProvider>;
844
+ developmentEmail: {
845
+ get(): Promise<import("./messaging").DevelopmentEmail>;
846
+ enable(body: import("./messaging").EnableDevelopmentEmailBody): Promise<import("./messaging").DevelopmentEmail>;
847
+ disable(): Promise<{
848
+ object: "development_email";
849
+ deleted: true;
850
+ provider_id: string;
851
+ mode: "standard";
852
+ }>;
853
+ };
854
+ managedEmail: {
855
+ get(): Promise<import("./messaging").ManagedEmail>;
856
+ create(body: import("./messaging").CreateManagedEmailBody): Promise<import("./messaging").ManagedEmail>;
857
+ verify(): Promise<import("./messaging").ManagedEmail>;
858
+ delete(options?: {
859
+ force?: boolean;
860
+ }): Promise<import("./messaging").DeletedManagedEmail>;
861
+ };
838
862
  test(channel: "email" | "sms", body: {
839
863
  to: string;
840
864
  }): Promise<import("./messaging").MessagingTestResult>;
@@ -882,6 +906,20 @@ declare function buildNamespaces(request: RequestFn): {
882
906
  get(): Promise<import("./instance").Instance>;
883
907
  update(body: import("./instance").UpdateInstanceBody): Promise<import("./instance").InstanceUpdateResult>;
884
908
  preflight(): Promise<import("./instance").PreflightReport>;
909
+ moveOrigin(body: import("./instance").OriginMoveRequest): Promise<import("./instance").OriginMove>;
910
+ connections(): Promise<import("./instance").InstanceConnections>;
911
+ integrations: {
912
+ chatly: {
913
+ get(): Promise<import("./instance").ChatlyIntegration>;
914
+ set(body: import("./instance").SetChatlyIntegrationBody): Promise<import("./instance").ChatlyIntegration>;
915
+ delete(): Promise<import("./instance").ChatlyIntegration>;
916
+ };
917
+ forumulate: {
918
+ get(): Promise<import("./instance").ForumulateIntegration>;
919
+ set(body: import("./instance").SetForumulateIntegrationBody): Promise<import("./instance").ForumulateIntegration>;
920
+ delete(): Promise<import("./instance").ForumulateIntegration>;
921
+ };
922
+ };
885
923
  cookieConsent: {
886
924
  get(): Promise<import("./instance").CookieConsent>;
887
925
  set(body: import("./instance").SetCookieConsentBody): Promise<import("./instance").CookieConsent>;
@@ -1200,6 +1238,20 @@ declare function buildNamespaces(request: RequestFn): {
1200
1238
  loginReadiness(params: import("./diagnostics").LoginReadinessParams): Promise<import("./diagnostics").LoginReadiness>;
1201
1239
  requestInspector(params: import("./diagnostics").RequestInspectorParams): Promise<import("./diagnostics").RequestInspection>;
1202
1240
  };
1241
+ logoutNotifyEndpoints: {
1242
+ list(): Promise<import("./logout-notify-endpoints").LogoutNotifyList<import("./logout-notify-endpoints").LogoutNotifyEndpoint>>;
1243
+ create(body: import("./logout-notify-endpoints").CreateLogoutNotifyEndpointBody, idempotencyKey?: string): Promise<import("./logout-notify-endpoints").LogoutNotifyEndpoint>;
1244
+ get(id: string): Promise<import("./logout-notify-endpoints").LogoutNotifyEndpoint>;
1245
+ update(id: string, body: import("./logout-notify-endpoints").UpdateLogoutNotifyEndpointBody, idempotencyKey?: string): Promise<import("./logout-notify-endpoints").LogoutNotifyEndpoint>;
1246
+ delete(id: string, idempotencyKey?: string): Promise<{
1247
+ object: "logout_notify_endpoint";
1248
+ id: string;
1249
+ deleted: true;
1250
+ }>;
1251
+ listDeliveries(id: string, params?: {
1252
+ limit?: number;
1253
+ }): Promise<import("./logout-notify-endpoints").LogoutNotifyList<import("./logout-notify-endpoints").LogoutNotifyDelivery>>;
1254
+ };
1203
1255
  };
1204
1256
  /** Every resource namespace of the management client. */
1205
1257
  export type AtlasClientNamespaces = ReturnType<typeof buildNamespaces>;
@@ -1282,4 +1334,5 @@ export * from './session-exchange-apps';
1282
1334
  export * from './tickets';
1283
1335
  export * from './test-mode';
1284
1336
  export * from './diagnostics';
1337
+ export * from './logout-notify-endpoints';
1285
1338
  export * from './platform';
@@ -72,6 +72,7 @@ const connectors_1 = require("./connectors");
72
72
  const notifications_1 = require("./notifications");
73
73
  const audit_events_1 = require("./audit-events");
74
74
  const activity_1 = require("./activity");
75
+ const logout_notify_endpoints_1 = require("./logout-notify-endpoints");
75
76
  const pca_1 = require("./pca");
76
77
  const mcp_1 = require("./mcp");
77
78
  const legacy_auth_1 = require("./legacy-auth");
@@ -175,6 +176,8 @@ function buildNamespaces(request) {
175
176
  // Development-instance helpers: the paired test instance, test users, testing tokens.
176
177
  testMode: (0, test_mode_1.testModeResource)(request),
177
178
  diagnostics: (0, diagnostics_1.diagnosticsResource)(request),
179
+ // Downstream services that get the same logout_token as your OIDC apps.
180
+ logoutNotifyEndpoints: (0, logout_notify_endpoints_1.logoutNotifyEndpointsResource)(request),
178
181
  };
179
182
  }
180
183
  var request_2 = require("./request");
@@ -253,5 +256,6 @@ __exportStar(require("./session-exchange-apps"), exports);
253
256
  __exportStar(require("./tickets"), exports);
254
257
  __exportStar(require("./test-mode"), exports);
255
258
  __exportStar(require("./diagnostics"), exports);
259
+ __exportStar(require("./logout-notify-endpoints"), exports);
256
260
  __exportStar(require("./platform"), exports);
257
261
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}