@atlasauth/backend 0.8.0 → 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.
- package/CHANGELOG.md +14 -0
- package/README.md +145 -0
- package/dist/client/email-templates.d.ts +1 -1
- package/dist/client/email-templates.js.map +1 -1
- package/dist/client/index.d.ts +11 -1
- package/dist/client/instance.d.ts +9 -0
- package/dist/client/instance.js.map +1 -1
- package/dist/client/messaging.d.ts +85 -8
- package/dist/client/messaging.js +19 -1
- package/dist/client/messaging.js.map +1 -1
- package/dist/client/oauth-clients.d.ts +25 -1
- package/dist/client/oauth-clients.js +11 -2
- package/dist/client/oauth-clients.js.map +1 -1
- package/dist/client/platform.d.ts +11 -0
- package/dist/client/platform.js.map +1 -1
- package/dist/client/users.d.ts +15 -0
- package/dist/client/users.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/oidc.d.ts +225 -0
- package/dist/oidc.js +631 -0
- package/dist/oidc.js.map +1 -0
- package/dist/testing.d.ts +90 -1
- package/dist/testing.js +202 -3
- package/dist/testing.js.map +1 -1
- package/dist/verify.d.ts +21 -0
- package/dist/verify.js +20 -0
- package/dist/verify.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
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
|
+
|
|
3
17
|
## 0.8.0
|
|
4
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.
|
|
5
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`).
|
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
|
|
@@ -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":";;
|
|
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"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -341,7 +341,7 @@ declare function buildNamespaces(request: RequestFn): {
|
|
|
341
341
|
get(id: string): Promise<import("./oauth-clients").OAuthClient>;
|
|
342
342
|
create(body: import("./oauth-clients").CreateOAuthClientBody, idempotencyKey?: string): Promise<import("./oauth-clients").OAuthClientWithSecret>;
|
|
343
343
|
update(id: string, body: import("./oauth-clients").UpdateOAuthClientBody): Promise<import("./oauth-clients").OAuthClient>;
|
|
344
|
-
rotateSecret(id: string): Promise<import("./oauth-clients").
|
|
344
|
+
rotateSecret(id: string, body?: import("./oauth-clients").RotateOAuthClientSecretBody, idempotencyKey?: string): Promise<import("./oauth-clients").OAuthClientSecretRotation>;
|
|
345
345
|
delete(id: string): Promise<{
|
|
346
346
|
object: "oauth_client";
|
|
347
347
|
id: string;
|
|
@@ -841,6 +841,16 @@ declare function buildNamespaces(request: RequestFn): {
|
|
|
841
841
|
deleteChannel(channel: "email" | "sms", options?: {
|
|
842
842
|
force?: boolean;
|
|
843
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
|
+
};
|
|
844
854
|
managedEmail: {
|
|
845
855
|
get(): Promise<import("./messaging").ManagedEmail>;
|
|
846
856
|
create(body: import("./messaging").CreateManagedEmailBody): Promise<import("./messaging").ManagedEmail>;
|
|
@@ -12,6 +12,15 @@ export interface Instance {
|
|
|
12
12
|
environment: string;
|
|
13
13
|
publishable_key: string;
|
|
14
14
|
frontend_api_host: string;
|
|
15
|
+
/**
|
|
16
|
+
* The `iss` this instance's session tokens carry. It changes when a custom
|
|
17
|
+
* domain goes active, so read it (and the two URLs below) rather than hard-coding it.
|
|
18
|
+
*/
|
|
19
|
+
issuer: string;
|
|
20
|
+
/** The OpenID discovery document whose `issuer` equals {@link issuer}. */
|
|
21
|
+
discovery_url: string;
|
|
22
|
+
/** The JWKS holding this instance's signing keys. */
|
|
23
|
+
jwks_uri: string;
|
|
15
24
|
allowed_origins: string[];
|
|
16
25
|
auth_config: Metadata;
|
|
17
26
|
created_at: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/client/instance.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/client/instance.ts"],"names":[],"mappings":";;AAkSA,4CAiEC;AAjED,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,MAAM,CAAC,IAAwB;YAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,yFAAyF;QACzF,SAAS;YACP,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACpE,CAAC;QACD;;;;WAIG;QACH,UAAU,CAAC,IAAuB;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,2EAA2E;QAC3E,WAAW;YACT,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,+CAA+C;QAC/C,YAAY,EAAE;YACZ,MAAM,EAAE;gBACN,GAAG;oBACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAAC,CAAC;gBAC9E,CAAC;gBACD,GAAG,CAAC,IAA8B;oBAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,kCAAkC,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpF,CAAC;gBACD,MAAM;oBACJ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAAC,CAAC;gBACjF,CAAC;aACF;YACD,UAAU,EAAE;gBACV,GAAG;oBACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,sCAAsC,EAAE,CAAC,CAAC;gBAClF,CAAC;gBACD,qCAAqC;gBACrC,GAAG,CAAC,IAAkC;oBACpC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,sCAAsC,EAAE,IAAI,EAAE,CAAC,CAAC;gBACxF,CAAC;gBACD,MAAM;oBACJ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,sCAAsC,EAAE,CAAC,CAAC;gBACrF,CAAC;aACF;SACF;QACD,oEAAoE;QACpE,aAAa,EAAE;YACb,GAAG;gBACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,kCAAkC;YAClC,GAAG,CAAC,IAA0B;gBAC5B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,6BAA6B,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,+EAA+E;YAC/E,MAAM;gBACJ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC;YAC5E,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -193,6 +193,12 @@ interface ProviderBodyBase<T extends MessagingTransport> {
|
|
|
193
193
|
* provider accepts. SMS: the sender number in E.164 format, e.g. `+15551234567`.
|
|
194
194
|
*/
|
|
195
195
|
from_address?: string;
|
|
196
|
+
/**
|
|
197
|
+
* Email only. `development`: a development instance sends without a verified
|
|
198
|
+
* domain (Atlas sign-in templates only, `[Atlas test] ` subjects, capped);
|
|
199
|
+
* 409 on a production instance. Omitted on an update: the stored mode is kept.
|
|
200
|
+
*/
|
|
201
|
+
mode?: 'standard' | 'development';
|
|
196
202
|
}
|
|
197
203
|
/**
|
|
198
204
|
* First setup of transport `T` (or a switch to it): `config` carries every
|
|
@@ -246,8 +252,12 @@ type PublicConfigKey<T extends MessagingTransport> = Exclude<keyof MessagingTran
|
|
|
246
252
|
*/
|
|
247
253
|
export interface MessagingProviderOf<C extends 'email' | 'sms', T extends MessagingTransport> {
|
|
248
254
|
object: 'messaging_provider';
|
|
255
|
+
/** The provider id: pass it as `provider_id` to managed email or the development sender. */
|
|
256
|
+
id?: string;
|
|
249
257
|
channel: C;
|
|
250
258
|
transport: T;
|
|
259
|
+
/** How it sends: `standard` | `development` | `managed_domain`. */
|
|
260
|
+
mode?: 'standard' | 'development' | 'managed_domain';
|
|
251
261
|
from_address: string | null;
|
|
252
262
|
status: string;
|
|
253
263
|
/** Non-secret config only — secret values are never returned. */
|
|
@@ -280,10 +290,16 @@ export interface MessagingProviders {
|
|
|
280
290
|
status: string;
|
|
281
291
|
verified: boolean;
|
|
282
292
|
} | null;
|
|
293
|
+
/** The email provider in development mode, when it is. */
|
|
294
|
+
development_email?: {
|
|
295
|
+
object: 'development_email';
|
|
296
|
+
enabled: true;
|
|
297
|
+
from_address: string | null;
|
|
298
|
+
} | null;
|
|
283
299
|
}
|
|
284
300
|
/** A DNS record to publish for the managed sending domain. */
|
|
285
301
|
export interface ManagedEmailRecord {
|
|
286
|
-
purpose: 'dkim' | 'spf' | 'return_path' | 'other';
|
|
302
|
+
purpose: 'dkim' | 'spf' | 'return_path' | 'ownership' | 'dmarc' | 'other';
|
|
287
303
|
type: 'TXT' | 'MX' | 'CNAME';
|
|
288
304
|
/** Fully-qualified record name. */
|
|
289
305
|
name: string;
|
|
@@ -291,22 +307,24 @@ export interface ManagedEmailRecord {
|
|
|
291
307
|
priority?: number;
|
|
292
308
|
status?: string;
|
|
293
309
|
}
|
|
294
|
-
/**
|
|
310
|
+
/** Managed email: Atlas sets your sending domain up on your own Resend or Brevo account and sends through your key. */
|
|
295
311
|
export interface ManagedEmail {
|
|
296
312
|
object: 'managed_email';
|
|
297
313
|
id: string;
|
|
298
314
|
from_address: string;
|
|
299
315
|
domain: string;
|
|
300
316
|
provider: string;
|
|
317
|
+
/** The email service the domain lives on (your own account there): `resend` | `brevo`. */
|
|
318
|
+
backend?: 'resend' | 'brevo';
|
|
319
|
+
/** Your email provider (mode `managed_domain`) that holds the API key. */
|
|
320
|
+
provider_id?: string | null;
|
|
301
321
|
region: string | null;
|
|
302
322
|
/** `not_started` | `pending` | `verified` | `failed` | `temporary_failure`. Email sends only when verified. */
|
|
303
323
|
status: string;
|
|
304
324
|
verified: boolean;
|
|
305
325
|
records: ManagedEmailRecord[];
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
daily: number;
|
|
309
|
-
};
|
|
326
|
+
/** Always null: no Atlas limits apply, your provider account's own do. */
|
|
327
|
+
limits: null;
|
|
310
328
|
usage: {
|
|
311
329
|
sent: number;
|
|
312
330
|
bounces: number;
|
|
@@ -314,7 +332,9 @@ export interface ManagedEmail {
|
|
|
314
332
|
last_bounce_at: number | null;
|
|
315
333
|
last_complaint_at: number | null;
|
|
316
334
|
};
|
|
317
|
-
reputation: '
|
|
335
|
+
reputation: 'your_provider_account';
|
|
336
|
+
/** Brevo, on create: whether the bounce / complaint webhook was registered on your account. */
|
|
337
|
+
feedback_webhook?: 'registered' | 'not_registered';
|
|
318
338
|
/** DNS automation, when set. The token is never returned. */
|
|
319
339
|
dns: {
|
|
320
340
|
provider: string;
|
|
@@ -332,6 +352,14 @@ export interface ManagedEmail {
|
|
|
332
352
|
export interface CreateManagedEmailBody {
|
|
333
353
|
/** The From address, bare or `"Name <address>"`. Its domain becomes the sending domain. */
|
|
334
354
|
from_address: string;
|
|
355
|
+
/** Your own provider account Atlas sets the domain up on. Required with `config` unless `provider_id` is given. */
|
|
356
|
+
transport?: 'resend' | 'brevo';
|
|
357
|
+
/** Your provider API key (write-only). */
|
|
358
|
+
config?: {
|
|
359
|
+
api_key: string;
|
|
360
|
+
};
|
|
361
|
+
/** Instead of `transport` + `config`: your configured Resend or Brevo email provider. */
|
|
362
|
+
provider_id?: string;
|
|
335
363
|
region?: 'us-east-1' | 'eu-west-1' | 'sa-east-1' | 'ap-northeast-1';
|
|
336
364
|
/** Let Atlas write the DNS records. The token is write-only. */
|
|
337
365
|
dns?: {
|
|
@@ -346,7 +374,39 @@ export interface DeletedManagedEmail {
|
|
|
346
374
|
object: 'managed_email';
|
|
347
375
|
domain: string;
|
|
348
376
|
deleted: true;
|
|
377
|
+
/** Whether the email provider that held the key (mode `managed_domain`) was removed too. */
|
|
378
|
+
provider_removed?: boolean;
|
|
349
379
|
}
|
|
380
|
+
/** Your own email provider in development mode (development instances, no verified domain). */
|
|
381
|
+
export interface DevelopmentEmail {
|
|
382
|
+
object: 'development_email';
|
|
383
|
+
provider_id: string;
|
|
384
|
+
enabled: true;
|
|
385
|
+
/** False on a production instance (never sends) or when the provider is disabled. */
|
|
386
|
+
active: boolean;
|
|
387
|
+
transport: string;
|
|
388
|
+
from_address: string | null;
|
|
389
|
+
subject_prefix: string;
|
|
390
|
+
footer: string;
|
|
391
|
+
templates: string[];
|
|
392
|
+
limits: {
|
|
393
|
+
daily: number;
|
|
394
|
+
per_recipient_hourly: number;
|
|
395
|
+
};
|
|
396
|
+
/** Present for onboarding@resend.dev: Resend delivers it only to your Resend account address. */
|
|
397
|
+
note?: string;
|
|
398
|
+
next_step?: string;
|
|
399
|
+
updated_at: number;
|
|
400
|
+
}
|
|
401
|
+
/** `{ provider_id }`, or your provider exactly as `messaging.setEmail` takes it. */
|
|
402
|
+
export type EnableDevelopmentEmailBody = {
|
|
403
|
+
provider_id: string;
|
|
404
|
+
from_address?: string;
|
|
405
|
+
} | {
|
|
406
|
+
transport: 'resend' | 'ses' | 'smtp' | 'brevo' | 'mailgun';
|
|
407
|
+
config?: Record<string, string>;
|
|
408
|
+
from_address?: string;
|
|
409
|
+
};
|
|
350
410
|
export interface MessagingTestResult {
|
|
351
411
|
object: 'messaging_test';
|
|
352
412
|
channel: string;
|
|
@@ -397,7 +457,24 @@ export declare function messagingResource(request: RequestFn): {
|
|
|
397
457
|
deleteChannel(channel: "email" | "sms", options?: {
|
|
398
458
|
force?: boolean;
|
|
399
459
|
}): Promise<DeletedMessagingProvider>;
|
|
400
|
-
/**
|
|
460
|
+
/**
|
|
461
|
+
* Your own email provider in development mode: a development instance sends
|
|
462
|
+
* Atlas's sign-in emails without a verified domain ([Atlas test] subjects, capped).
|
|
463
|
+
*/
|
|
464
|
+
developmentEmail: {
|
|
465
|
+
/** 404 when the provider is not in development mode. */
|
|
466
|
+
get(): Promise<DevelopmentEmail>;
|
|
467
|
+
/** Turn development mode on. 409 `DEVELOPMENT_EMAIL_NOT_ALLOWED` on a production instance. */
|
|
468
|
+
enable(body: EnableDevelopmentEmailBody): Promise<DevelopmentEmail>;
|
|
469
|
+
/** Back to standard mode; the provider stays. */
|
|
470
|
+
disable(): Promise<{
|
|
471
|
+
object: "development_email";
|
|
472
|
+
deleted: true;
|
|
473
|
+
provider_id: string;
|
|
474
|
+
mode: "standard";
|
|
475
|
+
}>;
|
|
476
|
+
};
|
|
477
|
+
/** Managed email: Atlas sets your sending domain up on your own Resend or Brevo account. */
|
|
401
478
|
managedEmail: {
|
|
402
479
|
/** 404 when none is configured. */
|
|
403
480
|
get(): Promise<ManagedEmail>;
|
package/dist/client/messaging.js
CHANGED
|
@@ -40,7 +40,25 @@ function messagingResource(request) {
|
|
|
40
40
|
...(options.force ? { query: { force: 'true' } } : {}),
|
|
41
41
|
});
|
|
42
42
|
},
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Your own email provider in development mode: a development instance sends
|
|
45
|
+
* Atlas's sign-in emails without a verified domain ([Atlas test] subjects, capped).
|
|
46
|
+
*/
|
|
47
|
+
developmentEmail: {
|
|
48
|
+
/** 404 when the provider is not in development mode. */
|
|
49
|
+
get() {
|
|
50
|
+
return request({ method: 'GET', path: '/v1/messaging_providers/email/development' });
|
|
51
|
+
},
|
|
52
|
+
/** Turn development mode on. 409 `DEVELOPMENT_EMAIL_NOT_ALLOWED` on a production instance. */
|
|
53
|
+
enable(body) {
|
|
54
|
+
return request({ method: 'POST', path: '/v1/messaging_providers/email/development', body });
|
|
55
|
+
},
|
|
56
|
+
/** Back to standard mode; the provider stays. */
|
|
57
|
+
disable() {
|
|
58
|
+
return request({ method: 'DELETE', path: '/v1/messaging_providers/email/development' });
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
/** Managed email: Atlas sets your sending domain up on your own Resend or Brevo account. */
|
|
44
62
|
managedEmail: {
|
|
45
63
|
/** 404 when none is configured. */
|
|
46
64
|
get() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messaging.js","sourceRoot":"","sources":["../../src/client/messaging.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"messaging.js","sourceRoot":"","sources":["../../src/client/messaging.ts"],"names":[],"mappings":";;AAydA,8CAuGC;AAhkBD,uCAAgD;AAydhD,SAAgB,iBAAiB,CAAC,OAAkB;IAIlD,SAAS,QAAQ,CAAC,IAAa;QAC7B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,+BAA+B,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,CAAC;IAKD,SAAS,MAAM,CAAC,IAAa;QAC3B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,6BAA6B,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO;QACL,0EAA0E;QAC1E,GAAG;YACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACrE,CAAC;QACD;;;;WAIG;QACH,QAAQ;QACR;;;;WAIG;QACH,MAAM;QACN;;;;;;WAMG;QACH,aAAa,CACX,OAAwB,EACxB,UAA+B,EAAE;YAEjC,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,2BAA2B,IAAA,aAAG,EAAC,OAAO,CAAC,EAAE;gBAC/C,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvD,CAAC,CAAC;QACL,CAAC;QACD;;;WAGG;QACH,gBAAgB,EAAE;YAChB,wDAAwD;YACxD,GAAG;gBACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,2CAA2C,EAAE,CAAC,CAAC;YACvF,CAAC;YACD,8FAA8F;YAC9F,MAAM,CAAC,IAAgC;gBACrC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,2CAA2C,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9F,CAAC;YACD,iDAAiD;YACjD,OAAO;gBACL,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,2CAA2C,EAAE,CAAC,CAAC;YAC1F,CAAC;SACF;QACD,4FAA4F;QAC5F,YAAY,EAAE;YACZ,mCAAmC;YACnC,GAAG;gBACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uCAAuC,EAAE,CAAC,CAAC;YACnF,CAAC;YACD,yEAAyE;YACzE,MAAM,CAAC,IAA4B;gBACjC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,uCAAuC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1F,CAAC;YACD,+EAA+E;YAC/E,MAAM;gBACJ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,8CAA8C,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD;;;;eAIG;YACH,MAAM,CAAC,UAA+B,EAAE;gBACtC,OAAO,OAAO,CAAC;oBACb,MAAM,EAAE,QAAQ;oBAChB,IAAI,EAAE,uCAAuC;oBAC7C,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvD,CAAC,CAAC;YACL,CAAC;SACF;QACD,gFAAgF;QAChF,IAAI,CAAC,OAAwB,EAAE,IAAoB;YACjD,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,2BAA2B,IAAA,aAAG,EAAC,OAAO,CAAC,OAAO;gBACpD,IAAI;aACL,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -11,6 +11,11 @@ export interface OAuthClient {
|
|
|
11
11
|
grant_types: string[];
|
|
12
12
|
token_endpoint_auth_method: 'client_secret_basic' | 'client_secret_post' | 'none';
|
|
13
13
|
secret_prefix: string | null;
|
|
14
|
+
/**
|
|
15
|
+
* After a rotation with overlap: when the previous secret stops working (epoch
|
|
16
|
+
* ms). Null when only the current secret is accepted.
|
|
17
|
+
*/
|
|
18
|
+
previous_secret_expires_at?: number | null;
|
|
14
19
|
is_public: boolean;
|
|
15
20
|
first_party: boolean;
|
|
16
21
|
/** Where the client may send users after an RP-initiated logout. */
|
|
@@ -51,6 +56,21 @@ export interface OAuthClientWithSecret extends OAuthClient {
|
|
|
51
56
|
client_secret?: string;
|
|
52
57
|
note: string;
|
|
53
58
|
}
|
|
59
|
+
export interface RotateOAuthClientSecretBody {
|
|
60
|
+
/**
|
|
61
|
+
* How long the previous secret keeps working, in seconds. Default 86400 (24
|
|
62
|
+
* hours); 0 revokes it now (after a leak); at most 604800 (7 days).
|
|
63
|
+
*/
|
|
64
|
+
overlap_seconds?: number;
|
|
65
|
+
}
|
|
66
|
+
/** The rotate response: the new secret (shown once) and when the old one stops working. */
|
|
67
|
+
export interface OAuthClientSecretRotation extends OAuthClientWithSecret {
|
|
68
|
+
client_secret: string;
|
|
69
|
+
/** The overlap applied, in seconds. */
|
|
70
|
+
overlap_seconds: number;
|
|
71
|
+
/** When the previous secret stops working (epoch ms), or null when it already has. */
|
|
72
|
+
previous_secret_expires_at: number | null;
|
|
73
|
+
}
|
|
54
74
|
export interface ClientGrant {
|
|
55
75
|
object: 'client_grant';
|
|
56
76
|
id: string;
|
|
@@ -162,7 +182,11 @@ export declare function oauthClientsResource(request: RequestFn): {
|
|
|
162
182
|
get(id: string): Promise<OAuthClient>;
|
|
163
183
|
create(body: CreateOAuthClientBody, idempotencyKey?: string): Promise<OAuthClientWithSecret>;
|
|
164
184
|
update(id: string, body: UpdateOAuthClientBody): Promise<OAuthClient>;
|
|
165
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Mint a new secret. The previous one keeps working for `overlap_seconds`
|
|
187
|
+
* (default 24 hours, max 7 days; 0 = revoke it now).
|
|
188
|
+
*/
|
|
189
|
+
rotateSecret(id: string, body?: RotateOAuthClientSecretBody, idempotencyKey?: string): Promise<OAuthClientSecretRotation>;
|
|
166
190
|
delete(id: string): Promise<{
|
|
167
191
|
object: "oauth_client";
|
|
168
192
|
id: string;
|
|
@@ -20,8 +20,17 @@ function oauthClientsResource(request) {
|
|
|
20
20
|
update(id, body) {
|
|
21
21
|
return request({ method: 'PATCH', path: `/v1/oauth_clients/${(0, request_1.enc)(id)}`, body });
|
|
22
22
|
},
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Mint a new secret. The previous one keeps working for `overlap_seconds`
|
|
25
|
+
* (default 24 hours, max 7 days; 0 = revoke it now).
|
|
26
|
+
*/
|
|
27
|
+
rotateSecret(id, body = {}, idempotencyKey) {
|
|
28
|
+
return request({
|
|
29
|
+
method: 'POST',
|
|
30
|
+
path: `/v1/oauth_clients/${(0, request_1.enc)(id)}/rotate_secret`,
|
|
31
|
+
body,
|
|
32
|
+
idempotencyKey,
|
|
33
|
+
});
|
|
25
34
|
},
|
|
26
35
|
delete(id) {
|
|
27
36
|
return request({ method: 'DELETE', path: `/v1/oauth_clients/${(0, request_1.enc)(id)}` });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-clients.js","sourceRoot":"","sources":["../../src/client/oauth-clients.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"oauth-clients.js","sourceRoot":"","sources":["../../src/client/oauth-clients.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,6 +40,17 @@ export interface PlatformApp {
|
|
|
40
40
|
name: string;
|
|
41
41
|
environment: 'production' | 'development';
|
|
42
42
|
publishable_key: string;
|
|
43
|
+
/** The Frontend API host: the default per-app host, or the custom domain once it is active. */
|
|
44
|
+
frontend_api_host: string | null;
|
|
45
|
+
/**
|
|
46
|
+
* The `iss` this app's session tokens carry. It changes when a custom domain
|
|
47
|
+
* goes active, so read it (and the two URLs below) rather than hard-coding it.
|
|
48
|
+
*/
|
|
49
|
+
issuer: string;
|
|
50
|
+
/** The OpenID discovery document whose `issuer` equals {@link issuer}. */
|
|
51
|
+
discovery_url: string;
|
|
52
|
+
/** The JWKS holding this app's signing keys. */
|
|
53
|
+
jwks_uri: string;
|
|
43
54
|
allowed_origins: string[];
|
|
44
55
|
/** Housekeeping labels (up to 20, each up to 40 chars). */
|
|
45
56
|
tags: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/client/platform.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/client/platform.ts"],"names":[],"mappings":"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"}
|
package/dist/client/users.d.ts
CHANGED
|
@@ -27,7 +27,22 @@ export interface EmailAddress {
|
|
|
27
27
|
object: 'email_address';
|
|
28
28
|
id: string;
|
|
29
29
|
email_address: string;
|
|
30
|
+
/**
|
|
31
|
+
* True only when the address was proven (an emailed code or link, a provider
|
|
32
|
+
* that vouches for it, or your backend). An address that signed up while
|
|
33
|
+
* `requireEmailVerification` was false is `false`.
|
|
34
|
+
*/
|
|
30
35
|
verified: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* `status` mirrors `verified`. `strategy` says how it was verified
|
|
38
|
+
* (`email_code`, `email_link`, `oauth`, `admin`, `import`, `scim`, `lti`), or
|
|
39
|
+
* `skipped` for an address held for sign-in but never proven; `null` when not
|
|
40
|
+
* verified. (Absent from servers older than this field.)
|
|
41
|
+
*/
|
|
42
|
+
verification?: {
|
|
43
|
+
status: 'verified' | 'unverified';
|
|
44
|
+
strategy?: string | null;
|
|
45
|
+
};
|
|
31
46
|
primary: boolean;
|
|
32
47
|
created_at: number;
|
|
33
48
|
}
|