@synqauth/js 0.0.0 → 0.2.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/dist/api-CeYAjkvX.js +467 -0
- package/dist/index.d.ts +392 -232
- package/dist/index.js +90 -5
- package/dist/{management-y9-9AIc-.d.ts → management-CWdCiiEv.d.ts} +668 -10
- package/dist/server.d.ts +108 -2
- package/dist/server.js +122 -2
- package/package.json +1 -1
- package/dist/api-Cf9K1Rc9.js +0 -163
package/dist/index.d.ts
CHANGED
|
@@ -1,236 +1,289 @@
|
|
|
1
|
-
import { a as Problem, c as SynqError, d as ERROR_CODES, f as SynqErrorCode, i as OAuthErrorCode, l as isSynqError, n as operations$1, o as SynqAnyErrorCode, r as paths$1, s as SynqClientErrorCode, t as components$1, u as problemError } from "./management-
|
|
2
|
-
//#region src/storage.d.ts
|
|
3
|
-
/**
|
|
4
|
-
* Where the client keeps what it must remember: the session, and a sign-in's
|
|
5
|
-
* transaction (its PKCE verifier, state and nonce) across the redirect to
|
|
6
|
-
* Synq and back. Any key-value store fits; each method may be async.
|
|
7
|
-
*
|
|
8
|
-
* Refresh tokens are kept only by a store that says it may hold them
|
|
9
|
-
* (`holdsRefreshTokens`): the memory store, or one on a server or in a
|
|
10
|
-
* device's secure storage. Everything else keeps the session without its
|
|
11
|
-
* refresh token, which then lives in the client's memory alone, so a refresh
|
|
12
|
-
* token never lands in `localStorage` or `sessionStorage`, where any script
|
|
13
|
-
* on the page reads it.
|
|
14
|
-
*
|
|
15
|
-
* Synq rotates refresh tokens and ends the whole grant when a used one comes
|
|
16
|
-
* back, so only one refresh may run at a time for one session. One client
|
|
17
|
-
* makes sure of that by itself. When several clients share a store (requests
|
|
18
|
-
* on one server, or replicas sharing a cookie or Redis), the store must give
|
|
19
|
-
* them a lock (`lock`); a store without one is for one client per process.
|
|
20
|
-
*/
|
|
21
|
-
interface SynqStorage {
|
|
22
|
-
get(key: string): string | null | undefined | Promise<string | null | undefined>;
|
|
23
|
-
set(key: string, value: string): void | Promise<void>;
|
|
24
|
-
remove(key: string): void | Promise<void>;
|
|
25
|
-
/** Whether this store may hold refresh tokens: true only for memory, a server or secure device storage. */
|
|
26
|
-
readonly holdsRefreshTokens?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Runs `fn` while no other holder of `name`'s lock runs, in any client
|
|
29
|
-
* sharing this store: the client refreshes inside it, and reads the
|
|
30
|
-
* session again first, so a refresh another client finished meanwhile is
|
|
31
|
-
* used rather than repeated. A store shared across requests or replicas
|
|
32
|
-
* must have one.
|
|
33
|
-
*/
|
|
34
|
-
lock?<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
|
35
|
-
/** The keys it holds, so the client can sweep away sign-ins that were never finished. */
|
|
36
|
-
keys?(): Iterable<string> | Promise<Iterable<string>>;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Keeps everything in this process's memory: the default, and the only store
|
|
40
|
-
* that holds refresh tokens unless told. Clients that share one share its
|
|
41
|
-
* lock, so they never refresh one session twice at once.
|
|
42
|
-
*/
|
|
43
|
-
export declare function memoryStorage(): SynqStorage;
|
|
44
|
-
/**
|
|
45
|
-
* The tab's `sessionStorage`: it ends with the tab, and no other tab reads
|
|
46
|
-
* it. As the session's store it keeps the access and ID tokens only, never
|
|
47
|
-
* the refresh token.
|
|
48
|
-
*/
|
|
49
|
-
export declare function browserSessionStorage(): SynqStorage;
|
|
50
|
-
/**
|
|
51
|
-
* The browser's `localStorage`, which every tab of the app's origin shares.
|
|
52
|
-
* Where a sign-in's transaction goes by default in a browser: a magic link
|
|
53
|
-
* or an email's link opens a new tab, which finishes the sign-in and comes
|
|
54
|
-
* back to the app there, so the tab that started it can't be the only one
|
|
55
|
-
* that knows it. Each transaction is kept under its own state, for an hour
|
|
56
|
-
* at most, deleted when it finishes, and swept away when stale. The price:
|
|
57
|
-
* any script on the app's origin can read a transaction meanwhile (its PKCE
|
|
58
|
-
* verifier and nonce, useless without the code Synq sends to the app's own
|
|
59
|
-
* redirect URI), as it can read anything else the app keeps. As the
|
|
60
|
-
* session's store it keeps the access and ID tokens only, never the refresh
|
|
61
|
-
* token.
|
|
62
|
-
*/
|
|
63
|
-
export declare function browserLocalStorage(): SynqStorage;
|
|
64
|
-
//#endregion
|
|
65
|
-
//#region src/client.d.ts
|
|
66
|
-
/** What a Synq client needs to know about the app it signs people in to. */
|
|
67
|
-
interface SynqClientOptions {
|
|
68
|
-
/** The brand's issuer URL, as the dashboard shows it (`https://<issuer-slug>.auth.<Synq's domain>`). */
|
|
69
|
-
issuer: string | URL;
|
|
70
|
-
/** The app's client_id, from the dashboard or the management API. */
|
|
71
|
-
clientId: string;
|
|
72
|
-
/**
|
|
73
|
-
* A confidential app's secret, sent with HTTP Basic. Only on a server:
|
|
74
|
-
* an app whose code reaches a browser has no secret.
|
|
75
|
-
*/
|
|
76
|
-
clientSecret?: string;
|
|
77
|
-
/** Where Synq sends the browser back with the code: one of the app's registered redirect URIs, exactly. */
|
|
78
|
-
redirectUri: string;
|
|
79
|
-
/** Where the browser lands after signing out: one of the app's registered post-logout URIs. */
|
|
80
|
-
postLogoutRedirectUri?: string;
|
|
81
|
-
/** The scopes to ask for: `openid` by default. Add `offline_access` for a refresh token. */
|
|
82
|
-
scope?: string;
|
|
83
|
-
/** The API the access token is for (RFC 8707): a registered API's identifier. Without it the token is only good for userinfo. */
|
|
84
|
-
resource?: string;
|
|
85
|
-
/**
|
|
86
|
-
* Where the session is kept: this process's memory by default. Clients
|
|
87
|
-
* that share a store (requests on a server, replicas) need one with a
|
|
88
|
-
* `lock`, so they never present one refresh token twice; without one, use
|
|
89
|
-
* one client per process.
|
|
90
|
-
*/
|
|
91
|
-
storage?: SynqStorage;
|
|
92
|
-
/**
|
|
93
|
-
* Where a sign-in's transaction is kept across the redirect: the browser's
|
|
94
|
-
* localStorage, which every tab of the app shares (a magic link finishes a
|
|
95
|
-
* sign-in in a new tab), and memory outside a browser.
|
|
96
|
-
*/
|
|
97
|
-
transactionStorage?: SynqStorage;
|
|
98
|
-
/** The `fetch` to call Synq with: the global one by default. */
|
|
99
|
-
fetch?: typeof fetch;
|
|
100
|
-
/** How many seconds before the access token expires `getAccessToken` gets a new one: 30 by default. */
|
|
101
|
-
refreshLeewaySeconds?: number;
|
|
102
|
-
}
|
|
103
|
-
/** What to ask for when sending someone to sign in. */
|
|
104
|
-
interface AuthorizationUrlOptions {
|
|
105
|
-
/** Go straight to one sign-in method of the hosted page (`synq_method`): `password`, `email`, `passkey`, `wallet`, `google`... */
|
|
106
|
-
method?: string;
|
|
107
|
-
/** The address or username to fill in (`login_hint`). */
|
|
108
|
-
loginHint?: string;
|
|
109
|
-
/** `login` to ask for a fresh sign-in, `none` to sign in without showing anything (or fail), `consent` to ask again. */
|
|
110
|
-
prompt?: 'none' | 'login' | 'consent' | 'select_account';
|
|
111
|
-
/**
|
|
112
|
-
* The longest ago, in seconds, the person may have signed in (`max_age`);
|
|
113
|
-
* the ID token's `auth_time` is checked against it. Sent only when given:
|
|
114
|
-
* Synq asks anyone whose sign-in time it never saw proved (a provider that
|
|
115
|
-
* says nothing of when, such as Discord) to sign in again whenever
|
|
116
|
-
* `max_age` is present, so ask for it only where a fresh sign-in matters.
|
|
117
|
-
*/
|
|
118
|
-
maxAge?: number;
|
|
119
|
-
/** The scopes for this sign-in, instead of the client's. */
|
|
120
|
-
scope?: string;
|
|
121
|
-
/** The API for this sign-in's access token, instead of the client's. */
|
|
122
|
-
resource?: string;
|
|
123
|
-
/**
|
|
124
|
-
* Other APIs the sign-in's grant should cover too (RFC 8707: one
|
|
125
|
-
* `resource` each). The code is still exchanged for `resource`'s token;
|
|
126
|
-
* another client sharing the session's store gets one for these by
|
|
127
|
-
* refreshing with its own `resource`, as @synqauth/nextjs does for the
|
|
128
|
-
* account API beside the app's own.
|
|
129
|
-
*/
|
|
130
|
-
additionalResources?: readonly string[];
|
|
131
|
-
/** Any other parameter Synq takes, such as `synq_intent`. They can't replace the flow's own (state, nonce, PKCE, redirect URI). */
|
|
132
|
-
params?: Readonly<Record<string, string>>;
|
|
133
|
-
/**
|
|
134
|
-
* Sends the request's parameters to the issuer first, as a pushed
|
|
135
|
-
* authorization request (RFC 9126), and answers a URL that carries only
|
|
136
|
-
* its reference: for a parameter that must never travel in a URL, such
|
|
137
|
-
* as a wallet's signature (`synq_siws`).
|
|
138
|
-
*/
|
|
139
|
-
pushed?: boolean;
|
|
140
|
-
}
|
|
141
|
-
/** The claims of a validated ID token: who signed in, when, and how. */
|
|
142
|
-
interface IdTokenClaims {
|
|
143
|
-
readonly iss: string;
|
|
144
|
-
readonly sub: string;
|
|
145
|
-
readonly aud: string | string[];
|
|
146
|
-
readonly iat: number;
|
|
147
|
-
readonly exp: number;
|
|
148
|
-
readonly auth_time?: number;
|
|
149
|
-
readonly amr?: string[];
|
|
150
|
-
readonly acr?: string;
|
|
151
|
-
readonly [claim: string]: unknown;
|
|
152
|
-
}
|
|
153
|
-
/** A signed-in session, without its refresh token, which the client keeps to itself. */
|
|
154
|
-
interface Session {
|
|
155
|
-
readonly accessToken: string;
|
|
156
|
-
readonly tokenType: string;
|
|
157
|
-
/** When the access token expires, in seconds since the epoch, when Synq said. */
|
|
158
|
-
readonly expiresAt: number | undefined;
|
|
159
|
-
readonly scope: string | undefined;
|
|
160
|
-
readonly idToken: string | undefined;
|
|
161
|
-
/** The ID token's claims, validated when it was issued. */
|
|
162
|
-
readonly claims: IdTokenClaims | undefined;
|
|
163
|
-
/** Whether the client holds a refresh token for this session. */
|
|
164
|
-
readonly refreshable: boolean;
|
|
165
|
-
}
|
|
166
|
-
/** A change to the session, as `subscribe` reports it. */
|
|
167
|
-
type SessionEvent = {
|
|
168
|
-
readonly type: 'signed-in';
|
|
169
|
-
readonly session: Session;
|
|
170
|
-
} | {
|
|
171
|
-
readonly type: 'refreshed';
|
|
172
|
-
readonly session: Session;
|
|
173
|
-
} | {
|
|
174
|
-
readonly type: 'signed-out';
|
|
175
|
-
readonly session: null;
|
|
176
|
-
};
|
|
177
|
-
/** What `signOut` takes: where the browser lands afterwards, and the `state` handed back there. */
|
|
178
|
-
interface SignOutOptions {
|
|
179
|
-
/** Where the browser lands afterwards, instead of the client's `postLogoutRedirectUri`. */
|
|
180
|
-
postLogoutRedirectUri?: string;
|
|
181
|
-
/** Handed back on the post-logout redirect. */
|
|
182
|
-
state?: string;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* A client for one app at one brand's issuer, made by `createSynqClient`: it
|
|
186
|
-
* signs people in with the authorization code flow, keeps the session, and
|
|
187
|
-
* refreshes and ends it.
|
|
188
|
-
*/
|
|
189
|
-
interface SynqClient {
|
|
190
|
-
/** The URL to send the browser to, to sign in; the transaction it starts is kept in `transactionStorage`. */
|
|
191
|
-
authorizationUrl(options?: AuthorizationUrlOptions): Promise<URL>;
|
|
192
|
-
/** In a browser: sends it to Synq to sign in. */
|
|
193
|
-
signIn(options?: AuthorizationUrlOptions): Promise<void>;
|
|
194
|
-
/** Finishes a sign-in from the URL Synq sent the browser back to; each transaction finishes once. */
|
|
195
|
-
handleCallback(url: string | URL): Promise<Session>;
|
|
196
|
-
/** The current session, or `null` when nobody is signed in. */
|
|
197
|
-
getSession(): Promise<Session | null>;
|
|
198
|
-
/**
|
|
199
|
-
* After a page loads: the session, while it can still give a current
|
|
200
|
-
* access token (its access token is good for the leeway, or the client
|
|
201
|
-
* holds its refresh token), or `null` when there is none. A session the
|
|
202
|
-
* browser kept without its refresh token, whose access token is running
|
|
203
|
-
* out, is ended here, and the browser is sent to Synq with `prompt=none` to
|
|
204
|
-
* sign the person in again without showing anything; it resolves `null` as
|
|
205
|
-
* the page leaves. On the way back, `handleCallback` signs them in, or
|
|
206
|
-
* fails with `login_required` when they are no longer signed in at Synq.
|
|
207
|
-
* Call it on page load, but not on the callback's own page.
|
|
208
|
-
*/
|
|
209
|
-
restoreSession(options?: Omit<AuthorizationUrlOptions, 'prompt'>): Promise<Session | null>;
|
|
210
|
-
/** A current access token, refreshed first when it expires within `minValiditySeconds` (the client's leeway by default). */
|
|
211
|
-
getAccessToken(options?: {
|
|
212
|
-
minValiditySeconds?: number;
|
|
213
|
-
}): Promise<string>;
|
|
214
|
-
/**
|
|
215
|
-
* Gets new tokens with the refresh token. Calls at once share one request:
|
|
216
|
-
* Synq rotates refresh tokens and treats a used one presented again as
|
|
217
|
-
* theft, ending the whole grant.
|
|
218
|
-
*/
|
|
219
|
-
refresh(): Promise<Session>;
|
|
220
|
-
/** Calls `listener` on every sign-in, refresh and sign-out; returns the function that stops it. */
|
|
221
|
-
subscribe(listener: (event: SessionEvent) => void): () => void;
|
|
222
|
-
/**
|
|
223
|
-
* Ends the session here, revokes its refresh token, and returns Synq's
|
|
224
|
-
* sign-out URL (RP-initiated logout), to send the browser to so the
|
|
225
|
-
* brand's session ends too: `null` when the issuer has none.
|
|
226
|
-
*/
|
|
227
|
-
signOut(options?: SignOutOptions): Promise<URL | null>;
|
|
228
|
-
}
|
|
229
|
-
/** A client for one app at one of a brand's Synq issuers. */
|
|
230
|
-
export declare function createSynqClient(options: SynqClientOptions): SynqClient;
|
|
231
|
-
//#endregion
|
|
1
|
+
import { A as SignInFlowStep, C as browserLocalStorage, D as PasskeyRequestOptionsJSON, E as PasskeyAssertionJSON, F as ChallengeMethod, I as ChallengeProblem, L as DeniedReason, M as StartSignInOptions, N as CHALLENGE_METHODS, O as SavedSignIn, P as CHALLENGE_PROBLEMS, R as RedirectReason, S as SynqStorage, T as memoryStorage, _ as SessionEvent, a as Problem, b as SynqClientOptions, c as SynqError, d as ERROR_CODES, f as SynqErrorCode, g as Session, h as ServerSignInOptions, i as OAuthErrorCode, j as SignInStepResult, k as SignInFlow, l as isSynqError, m as IdTokenClaims, n as operations$1, o as SynqAnyErrorCode, p as AuthorizationUrlOptions, r as paths$1, s as SynqClientErrorCode, t as components$1, u as problemError, v as SignOutOptions, w as browserSessionStorage, x as createSynqClient, y as SynqClient } from "./management-CWdCiiEv.js";
|
|
232
2
|
//#region src/generated/account.d.ts
|
|
233
3
|
interface paths {
|
|
4
|
+
readonly "/v1/api-keys": {
|
|
5
|
+
readonly parameters: {
|
|
6
|
+
readonly query?: never;
|
|
7
|
+
readonly header?: never;
|
|
8
|
+
readonly path?: never;
|
|
9
|
+
readonly cookie?: never;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The signed-in person's API keys
|
|
13
|
+
* @description Oldest first, revoked and expired ones too; never a key itself. Needs `me:read`.
|
|
14
|
+
*/
|
|
15
|
+
readonly get: {
|
|
16
|
+
readonly parameters: {
|
|
17
|
+
readonly query?: never;
|
|
18
|
+
readonly header?: never;
|
|
19
|
+
readonly path?: never;
|
|
20
|
+
readonly cookie?: never;
|
|
21
|
+
};
|
|
22
|
+
readonly requestBody?: never;
|
|
23
|
+
readonly responses: {
|
|
24
|
+
/** @description Their API keys */
|
|
25
|
+
readonly 200: {
|
|
26
|
+
headers: {
|
|
27
|
+
readonly [name: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
content: {
|
|
30
|
+
readonly "application/json": {
|
|
31
|
+
readonly data: readonly components["schemas"]["UserApiKey"][];
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** @description No access token for this API, or one that is not valid */
|
|
36
|
+
readonly 401: {
|
|
37
|
+
headers: {
|
|
38
|
+
readonly [name: string]: unknown;
|
|
39
|
+
};
|
|
40
|
+
content: {
|
|
41
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
/** @description The token lacks the scope this route needs */
|
|
45
|
+
readonly 403: {
|
|
46
|
+
headers: {
|
|
47
|
+
readonly [name: string]: unknown;
|
|
48
|
+
};
|
|
49
|
+
content: {
|
|
50
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
/** @description Too many requests */
|
|
54
|
+
readonly 429: {
|
|
55
|
+
headers: {
|
|
56
|
+
readonly [name: string]: unknown;
|
|
57
|
+
};
|
|
58
|
+
content: {
|
|
59
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
readonly put?: never;
|
|
65
|
+
/**
|
|
66
|
+
* Make an API key
|
|
67
|
+
* @description A key for one of the brand's APIs that lets its users make them (`GET /v1/apis`): `ak_live_…` in production, `ak_test_…` elsewhere, in this response only. It acts as the person, with the scopes given, until it is revoked or expires, or the API stops letting its users make keys. At most 25 live at once. Needs `me:write`, from a sign-in in the last 5 minutes whose time Synq proved (send the person to sign in with `max_age=300`; a provider that can't show when they signed in, such as Discord, never counts), else 403 `fresh_sign_in_required`. Send `max_age` only when you need a fresh sign-in: it asks someone signed in that way to sign in again. Recorded as `user.api_key_created`.
|
|
68
|
+
*/
|
|
69
|
+
readonly post: {
|
|
70
|
+
readonly parameters: {
|
|
71
|
+
readonly query?: never;
|
|
72
|
+
readonly header?: never;
|
|
73
|
+
readonly path?: never;
|
|
74
|
+
readonly cookie?: never;
|
|
75
|
+
};
|
|
76
|
+
readonly requestBody: {
|
|
77
|
+
readonly content: {
|
|
78
|
+
readonly "application/json": components["schemas"]["UserApiKeyCreate"];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
readonly responses: {
|
|
82
|
+
/** @description The new key */
|
|
83
|
+
readonly 201: {
|
|
84
|
+
headers: {
|
|
85
|
+
readonly [name: string]: unknown;
|
|
86
|
+
};
|
|
87
|
+
content: {
|
|
88
|
+
readonly "application/json": components["schemas"]["NewUserApiKey"];
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/** @description A body that is not valid: an API none lists, a scope it doesn’t define, or an expiry not ahead */
|
|
92
|
+
readonly 400: {
|
|
93
|
+
headers: {
|
|
94
|
+
readonly [name: string]: unknown;
|
|
95
|
+
};
|
|
96
|
+
content: {
|
|
97
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
/** @description No access token for this API, or one that is not valid */
|
|
101
|
+
readonly 401: {
|
|
102
|
+
headers: {
|
|
103
|
+
readonly [name: string]: unknown;
|
|
104
|
+
};
|
|
105
|
+
content: {
|
|
106
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
/** @description The token lacks `me:write` (`insufficient_permissions`), the sign-in isn’t recent enough (`fresh_sign_in_required`), or the API doesn’t let its users make keys (`api_keys_not_allowed`) */
|
|
110
|
+
readonly 403: {
|
|
111
|
+
headers: {
|
|
112
|
+
readonly [name: string]: unknown;
|
|
113
|
+
};
|
|
114
|
+
content: {
|
|
115
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/** @description The person has 25 live keys already (`api_key_limit_reached`) */
|
|
119
|
+
readonly 409: {
|
|
120
|
+
headers: {
|
|
121
|
+
readonly [name: string]: unknown;
|
|
122
|
+
};
|
|
123
|
+
content: {
|
|
124
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
/** @description Too many requests */
|
|
128
|
+
readonly 429: {
|
|
129
|
+
headers: {
|
|
130
|
+
readonly [name: string]: unknown;
|
|
131
|
+
};
|
|
132
|
+
content: {
|
|
133
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
readonly delete?: never;
|
|
139
|
+
readonly options?: never;
|
|
140
|
+
readonly head?: never;
|
|
141
|
+
readonly patch?: never;
|
|
142
|
+
readonly trace?: never;
|
|
143
|
+
};
|
|
144
|
+
readonly "/v1/api-keys/{key}": {
|
|
145
|
+
readonly parameters: {
|
|
146
|
+
readonly query?: never;
|
|
147
|
+
readonly header?: never;
|
|
148
|
+
readonly path?: never;
|
|
149
|
+
readonly cookie?: never;
|
|
150
|
+
};
|
|
151
|
+
readonly get?: never;
|
|
152
|
+
readonly put?: never;
|
|
153
|
+
readonly post?: never;
|
|
154
|
+
/**
|
|
155
|
+
* Revoke an API key
|
|
156
|
+
* @description At once: its API's next check of it answers `active: false`. Needs `me:write`. Recorded as `user.api_key_revoked`.
|
|
157
|
+
*/
|
|
158
|
+
readonly delete: {
|
|
159
|
+
readonly parameters: {
|
|
160
|
+
readonly query?: never;
|
|
161
|
+
readonly header?: never;
|
|
162
|
+
readonly path: {
|
|
163
|
+
readonly key: string;
|
|
164
|
+
};
|
|
165
|
+
readonly cookie?: never;
|
|
166
|
+
};
|
|
167
|
+
readonly requestBody?: never;
|
|
168
|
+
readonly responses: {
|
|
169
|
+
/** @description Revoked */
|
|
170
|
+
readonly 204: {
|
|
171
|
+
headers: {
|
|
172
|
+
readonly [name: string]: unknown;
|
|
173
|
+
};
|
|
174
|
+
content?: never;
|
|
175
|
+
};
|
|
176
|
+
/** @description No access token for this API, or one that is not valid */
|
|
177
|
+
readonly 401: {
|
|
178
|
+
headers: {
|
|
179
|
+
readonly [name: string]: unknown;
|
|
180
|
+
};
|
|
181
|
+
content: {
|
|
182
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
/** @description The token lacks the scope this route needs */
|
|
186
|
+
readonly 403: {
|
|
187
|
+
headers: {
|
|
188
|
+
readonly [name: string]: unknown;
|
|
189
|
+
};
|
|
190
|
+
content: {
|
|
191
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
/** @description No such live key */
|
|
195
|
+
readonly 404: {
|
|
196
|
+
headers: {
|
|
197
|
+
readonly [name: string]: unknown;
|
|
198
|
+
};
|
|
199
|
+
content: {
|
|
200
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
/** @description Too many requests */
|
|
204
|
+
readonly 429: {
|
|
205
|
+
headers: {
|
|
206
|
+
readonly [name: string]: unknown;
|
|
207
|
+
};
|
|
208
|
+
content: {
|
|
209
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
readonly options?: never;
|
|
215
|
+
readonly head?: never;
|
|
216
|
+
readonly patch?: never;
|
|
217
|
+
readonly trace?: never;
|
|
218
|
+
};
|
|
219
|
+
readonly "/v1/apis": {
|
|
220
|
+
readonly parameters: {
|
|
221
|
+
readonly query?: never;
|
|
222
|
+
readonly header?: never;
|
|
223
|
+
readonly path?: never;
|
|
224
|
+
readonly cookie?: never;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* The APIs the person may make API keys for
|
|
228
|
+
* @description The brand's APIs whose tenant lets its users make API keys for them, with the scopes each defines, by name. Needs `me:read`.
|
|
229
|
+
*/
|
|
230
|
+
readonly get: {
|
|
231
|
+
readonly parameters: {
|
|
232
|
+
readonly query?: never;
|
|
233
|
+
readonly header?: never;
|
|
234
|
+
readonly path?: never;
|
|
235
|
+
readonly cookie?: never;
|
|
236
|
+
};
|
|
237
|
+
readonly requestBody?: never;
|
|
238
|
+
readonly responses: {
|
|
239
|
+
/** @description The APIs */
|
|
240
|
+
readonly 200: {
|
|
241
|
+
headers: {
|
|
242
|
+
readonly [name: string]: unknown;
|
|
243
|
+
};
|
|
244
|
+
content: {
|
|
245
|
+
readonly "application/json": {
|
|
246
|
+
readonly data: readonly components["schemas"]["KeyableApi"][];
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
/** @description No access token for this API, or one that is not valid */
|
|
251
|
+
readonly 401: {
|
|
252
|
+
headers: {
|
|
253
|
+
readonly [name: string]: unknown;
|
|
254
|
+
};
|
|
255
|
+
content: {
|
|
256
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
/** @description The token lacks the scope this route needs */
|
|
260
|
+
readonly 403: {
|
|
261
|
+
headers: {
|
|
262
|
+
readonly [name: string]: unknown;
|
|
263
|
+
};
|
|
264
|
+
content: {
|
|
265
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
/** @description Too many requests */
|
|
269
|
+
readonly 429: {
|
|
270
|
+
headers: {
|
|
271
|
+
readonly [name: string]: unknown;
|
|
272
|
+
};
|
|
273
|
+
content: {
|
|
274
|
+
readonly "application/problem+json": components["schemas"]["Problem"];
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
readonly put?: never;
|
|
280
|
+
readonly post?: never;
|
|
281
|
+
readonly delete?: never;
|
|
282
|
+
readonly options?: never;
|
|
283
|
+
readonly head?: never;
|
|
284
|
+
readonly patch?: never;
|
|
285
|
+
readonly trace?: never;
|
|
286
|
+
};
|
|
234
287
|
readonly "/v1/consents": {
|
|
235
288
|
readonly parameters: {
|
|
236
289
|
readonly query?: never;
|
|
@@ -1752,6 +1805,11 @@ interface components {
|
|
|
1752
1805
|
readonly Identity: {
|
|
1753
1806
|
/** Format: date-time */
|
|
1754
1807
|
readonly created_at: string;
|
|
1808
|
+
/**
|
|
1809
|
+
* @description Their handle there, without the @, as the provider showed it at their last sign-in with it: X’s, Discord’s, Telegram’s and Matrica’s username. Null where the provider has none. For showing people only: it changes, and never identifies anyone
|
|
1810
|
+
* @example ada
|
|
1811
|
+
*/
|
|
1812
|
+
readonly handle: string | null;
|
|
1755
1813
|
/** @example idn_01h455vb4pex5vsknk084sn02q */
|
|
1756
1814
|
readonly id: string;
|
|
1757
1815
|
/** Format: date-time */
|
|
@@ -1763,6 +1821,15 @@ interface components {
|
|
|
1763
1821
|
/** @description Who the person is there: a wallet address (`solana`), their email address (`email`), or the provider’s own id for them */
|
|
1764
1822
|
readonly subject: string;
|
|
1765
1823
|
};
|
|
1824
|
+
readonly KeyableApi: {
|
|
1825
|
+
/** @example https://api.acme.example */
|
|
1826
|
+
readonly identifier: string;
|
|
1827
|
+
readonly name: string;
|
|
1828
|
+
readonly scopes: readonly {
|
|
1829
|
+
readonly description: string;
|
|
1830
|
+
readonly name: string;
|
|
1831
|
+
}[];
|
|
1832
|
+
};
|
|
1766
1833
|
readonly LinkRequest: {
|
|
1767
1834
|
/** @description Add these to an authorization request from the same app (its own PKCE, state and redirect URI): the person signs in again as themselves, then uses the method, which joins their account. The request works for 10 minutes, for this person through this app, and only with that sign-in in the browser; it authorizes nothing by itself. */
|
|
1768
1835
|
readonly authorization_params: {
|
|
@@ -1793,6 +1860,13 @@ interface components {
|
|
|
1793
1860
|
readonly [key: string]: unknown;
|
|
1794
1861
|
};
|
|
1795
1862
|
};
|
|
1863
|
+
readonly NewUserApiKey: components["schemas"]["UserApiKey"] & {
|
|
1864
|
+
/**
|
|
1865
|
+
* @description The key itself, shown this once. Only its hash is kept.
|
|
1866
|
+
* @example ak_live_Ab3dEf…
|
|
1867
|
+
*/
|
|
1868
|
+
readonly key: string;
|
|
1869
|
+
};
|
|
1796
1870
|
readonly Passkey: {
|
|
1797
1871
|
/** @description Whether a synced passkey is backed up now */
|
|
1798
1872
|
readonly backed_up: boolean;
|
|
@@ -1879,6 +1953,11 @@ interface components {
|
|
|
1879
1953
|
readonly id: string;
|
|
1880
1954
|
/** Format: date-time */
|
|
1881
1955
|
readonly signed_in_at: string | null;
|
|
1956
|
+
/**
|
|
1957
|
+
* @description Where it was signed in: the brand's hosted page, or an app's own screens, whose session no browser holds
|
|
1958
|
+
* @enum {string}
|
|
1959
|
+
*/
|
|
1960
|
+
readonly via: "hosted" | "app";
|
|
1882
1961
|
};
|
|
1883
1962
|
readonly SignIn: {
|
|
1884
1963
|
readonly amr: readonly string[];
|
|
@@ -1889,6 +1968,61 @@ interface components {
|
|
|
1889
1968
|
/** @example email */
|
|
1890
1969
|
readonly provider: string;
|
|
1891
1970
|
};
|
|
1971
|
+
readonly UserApiKey: {
|
|
1972
|
+
readonly api: {
|
|
1973
|
+
/** @example https://api.acme.example */
|
|
1974
|
+
readonly identifier: string;
|
|
1975
|
+
readonly name: string;
|
|
1976
|
+
};
|
|
1977
|
+
/** Format: date-time */
|
|
1978
|
+
readonly created_at: string;
|
|
1979
|
+
/** Format: date-time */
|
|
1980
|
+
readonly expires_at: string | null;
|
|
1981
|
+
/** @example uak_01h455vb4pex5vsknk084sn02q */
|
|
1982
|
+
readonly id: string;
|
|
1983
|
+
/**
|
|
1984
|
+
* Format: date-time
|
|
1985
|
+
* @description When its API last checked it, to the minute
|
|
1986
|
+
*/
|
|
1987
|
+
readonly last_used_at: string | null;
|
|
1988
|
+
/** @example Reports script */
|
|
1989
|
+
readonly name: string;
|
|
1990
|
+
/**
|
|
1991
|
+
* @description The start of the key, to tell keys apart
|
|
1992
|
+
* @example ak_live_Ab3d
|
|
1993
|
+
*/
|
|
1994
|
+
readonly prefix: string;
|
|
1995
|
+
/** Format: date-time */
|
|
1996
|
+
readonly revoked_at: string | null;
|
|
1997
|
+
/**
|
|
1998
|
+
* @description What it may do: scopes of its API (one the API drops leaves every key)
|
|
1999
|
+
* @example [
|
|
2000
|
+
* "reports:read"
|
|
2001
|
+
* ]
|
|
2002
|
+
*/
|
|
2003
|
+
readonly scopes: readonly string[];
|
|
2004
|
+
};
|
|
2005
|
+
readonly UserApiKeyCreate: {
|
|
2006
|
+
/**
|
|
2007
|
+
* @description The API's identifier, one `GET /v1/apis` lists
|
|
2008
|
+
* @example https://api.acme.example
|
|
2009
|
+
*/
|
|
2010
|
+
readonly api: string;
|
|
2011
|
+
/**
|
|
2012
|
+
* Format: date-time
|
|
2013
|
+
* @description When it stops working, within 366 days; never, when not given
|
|
2014
|
+
*/
|
|
2015
|
+
readonly expires_at?: string;
|
|
2016
|
+
/** @example Reports script */
|
|
2017
|
+
readonly name: string;
|
|
2018
|
+
/**
|
|
2019
|
+
* @description What it may do: scopes the API defines
|
|
2020
|
+
* @example [
|
|
2021
|
+
* "reports:read"
|
|
2022
|
+
* ]
|
|
2023
|
+
*/
|
|
2024
|
+
readonly scopes: readonly string[];
|
|
2025
|
+
};
|
|
1892
2026
|
readonly UsernameAvailability: {
|
|
1893
2027
|
readonly available: boolean;
|
|
1894
2028
|
/** @enum {string|null} */
|
|
@@ -1952,6 +2086,14 @@ type AccountLinkRequest = Schemas['LinkRequest'];
|
|
|
1952
2086
|
type AccountUsernameAvailability = Schemas['UsernameAvailability'];
|
|
1953
2087
|
/** A way to sign in a link request can add. */
|
|
1954
2088
|
type LinkMethod = Schemas['NewLinkRequest']['method'];
|
|
2089
|
+
/** One of the person's API keys for the brand's APIs (AERO-1693): never the key itself. */
|
|
2090
|
+
type AccountApiKey = Schemas['UserApiKey'];
|
|
2091
|
+
/** A new API key: `key` is the key itself, in this answer only. */
|
|
2092
|
+
type AccountNewApiKey = Schemas['NewUserApiKey'];
|
|
2093
|
+
/** What `apiKeys.create()` takes: the API's identifier, a name, its scopes, and an expiry if any. */
|
|
2094
|
+
type AccountApiKeyCreate = Schemas['UserApiKeyCreate'];
|
|
2095
|
+
/** An API the person may make keys for, with the scopes it defines. */
|
|
2096
|
+
type AccountKeyableApi = Schemas['KeyableApi'];
|
|
1955
2097
|
/** A call's outcome: its data, or the `SynqError` it failed with (branch on `error.code`). */
|
|
1956
2098
|
type AccountResult<T> = {
|
|
1957
2099
|
readonly data: T;
|
|
@@ -2033,6 +2175,24 @@ interface AccountClient {
|
|
|
2033
2175
|
list: (options?: ReadOptions) => Promise<AccountResult<readonly AccountConsent[]>>;
|
|
2034
2176
|
withdraw: (consent: string, options?: ChangeOptions) => Promise<AccountResult<null>>;
|
|
2035
2177
|
};
|
|
2178
|
+
/**
|
|
2179
|
+
* Their API keys for the brand's own APIs (AERO-1693): what a script of
|
|
2180
|
+
* theirs sends the brand's API in place of an access token.
|
|
2181
|
+
*/
|
|
2182
|
+
apiKeys: {
|
|
2183
|
+
/** The brand's APIs that let them make keys, with each scope it defines. */
|
|
2184
|
+
apis: (options?: ReadOptions) => Promise<AccountResult<readonly AccountKeyableApi[]>>;
|
|
2185
|
+
/** Their keys, revoked and expired ones too; never a key itself. */
|
|
2186
|
+
list: (options?: ReadOptions) => Promise<AccountResult<readonly AccountApiKey[]>>;
|
|
2187
|
+
/**
|
|
2188
|
+
* Makes a key: its `key` is in this answer only, so show it once. Needs
|
|
2189
|
+
* a sign-in from the last 5 minutes (`fresh_sign_in_required`: sign in
|
|
2190
|
+
* again with `maxAge: 300`).
|
|
2191
|
+
*/
|
|
2192
|
+
create: (input: AccountApiKeyCreate, options?: ChangeOptions) => Promise<AccountResult<AccountNewApiKey>>;
|
|
2193
|
+
/** Revokes a key at once. */
|
|
2194
|
+
revoke: (key: string, options?: ChangeOptions) => Promise<AccountResult<null>>;
|
|
2195
|
+
};
|
|
2036
2196
|
/** Their recent sign-ins, newest first. */
|
|
2037
2197
|
activity: (options?: ReadOptions) => Promise<AccountResult<readonly AccountSignIn[]>>;
|
|
2038
2198
|
deletion: {
|
|
@@ -2052,4 +2212,4 @@ export declare function accountApiUrl(issuer: string | URL): string;
|
|
|
2052
2212
|
/** A client for the brand's account API, for an app that holds its own session: everything the signed-in person can do to their own account. */
|
|
2053
2213
|
export declare function createAccountClient(options: AccountClientOptions): AccountClient;
|
|
2054
2214
|
//#endregion
|
|
2055
|
-
export { type AccountClient, type AccountClientOptions, type components as AccountComponents, type AccountConsent, type AccountIdentity, type AccountLinkRequest, type operations as AccountOperations, type AccountPasskey, type paths as AccountPaths, type AccountProfile, type AccountProfileUpdate, type AccountResult, type AccountSession, type AccountSignIn, type AccountUsernameAvailability, type AccountWallet, type AccountWalletUpdate, type AuthorizationUrlOptions, type ChangeOptions, ERROR_CODES, type IdTokenClaims, type LinkMethod, type components$1 as ManagementComponents, type operations$1 as ManagementOperations, type paths$1 as ManagementPaths, type OAuthErrorCode, type Problem, type ReadOptions, type Session, type SessionEvent, type SignOutOptions, type SynqAnyErrorCode, type SynqClient, type SynqClientErrorCode, type SynqClientOptions, SynqError, type SynqErrorCode, type SynqStorage, isSynqError, problemError };
|
|
2215
|
+
export { type AccountApiKey, type AccountApiKeyCreate, type AccountClient, type AccountClientOptions, type components as AccountComponents, type AccountConsent, type AccountIdentity, type AccountKeyableApi, type AccountLinkRequest, type AccountNewApiKey, type operations as AccountOperations, type AccountPasskey, type paths as AccountPaths, type AccountProfile, type AccountProfileUpdate, type AccountResult, type AccountSession, type AccountSignIn, type AccountUsernameAvailability, type AccountWallet, type AccountWalletUpdate, type AuthorizationUrlOptions, CHALLENGE_METHODS, CHALLENGE_PROBLEMS, type ChallengeMethod, type ChallengeProblem, type ChangeOptions, type DeniedReason, ERROR_CODES, type IdTokenClaims, type LinkMethod, type components$1 as ManagementComponents, type operations$1 as ManagementOperations, type paths$1 as ManagementPaths, type OAuthErrorCode, type PasskeyAssertionJSON, type PasskeyRequestOptionsJSON, type Problem, type ReadOptions, type RedirectReason, type SavedSignIn, type ServerSignInOptions, type Session, type SessionEvent, SignInFlow, type SignInFlowStep, type SignInStepResult, type SignOutOptions, type StartSignInOptions, type SynqAnyErrorCode, type SynqClient, type SynqClientErrorCode, type SynqClientOptions, SynqError, type SynqErrorCode, type SynqStorage, browserLocalStorage, browserSessionStorage, createSynqClient, isSynqError, memoryStorage, problemError };
|