@atlasauth/backend 0.2.0 → 0.5.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/client/api-keys.d.ts +50 -1
- package/dist/client/api-keys.js +14 -0
- package/dist/client/api-keys.js.map +1 -1
- package/dist/client/index.d.ts +40 -2
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/machines.d.ts +183 -0
- package/dist/client/machines.js +73 -0
- package/dist/client/machines.js.map +1 -0
- package/dist/client/messaging.d.ts +287 -21
- package/dist/client/messaging.js +18 -6
- package/dist/client/messaging.js.map +1 -1
- package/dist/discovery.d.ts +49 -0
- package/dist/discovery.js +143 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/jwks-cache.d.ts +8 -0
- package/dist/jwks-cache.js +20 -3
- package/dist/jwks-cache.js.map +1 -1
- package/dist/pca/require-pca.d.ts +47 -0
- package/dist/pca/require-pca.js +121 -0
- package/dist/pca/require-pca.js.map +1 -0
- package/dist/pca/verify.d.ts +36 -0
- package/dist/pca/verify.js +136 -0
- package/dist/pca/verify.js.map +1 -0
- package/dist/verify.d.ts +19 -3
- package/dist/verify.js +27 -5
- package/dist/verify.js.map +1 -1
- package/package.json +3 -2
|
@@ -1,30 +1,235 @@
|
|
|
1
1
|
import { type RequestFn } from './request';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Messaging providers — wire your own email or SMS provider (Resend, SES, SMTP,
|
|
4
|
+
* Brevo, Mailgun; Twilio, Vonage, MessageBird, Plivo, Telnyx, Sinch, Infobip,
|
|
5
|
+
* ClickSend, Bandwidth, AWS SNS) over the secret-key Backend API.
|
|
6
|
+
*
|
|
7
|
+
* Each transport accepts an exact set of `config` keys; the API refuses an
|
|
8
|
+
* unknown key with a 422 naming `config.<key>`. These types mirror that schema,
|
|
9
|
+
* so a typo or another provider's key name fails to compile.
|
|
5
10
|
*
|
|
6
11
|
* A provider SECRET is WRITE-ONLY: it goes in through `config` and is never
|
|
7
12
|
* read back — a response reports only WHICH secret keys are set (`secrets_set`).
|
|
8
|
-
*
|
|
9
|
-
*
|
|
13
|
+
*
|
|
14
|
+
* Required keys: every key marked "Required on first setup" must be sent the
|
|
15
|
+
* first time you configure a transport (or when you switch the channel to a
|
|
16
|
+
* different transport). When you update the SAME transport, the stored config is
|
|
17
|
+
* kept: omit a key — or send it as `''` — and its stored value (including a
|
|
18
|
+
* stored secret) stays. So a from-address change need not re-enter the API key.
|
|
10
19
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
secrets_set: Record<string, boolean>;
|
|
21
|
-
updated_at: number;
|
|
20
|
+
/** Email transports accepted by `PUT /v1/messaging_providers/email`. */
|
|
21
|
+
export type EmailTransport = 'resend' | 'ses' | 'smtp' | 'brevo' | 'mailgun';
|
|
22
|
+
/** SMS transports accepted by `PUT /v1/messaging_providers/sms`. */
|
|
23
|
+
export type SmsTransport = 'twilio' | 'vonage' | 'messagebird' | 'plivo' | 'telnyx' | 'sinch' | 'infobip' | 'clicksend' | 'bandwidth' | 'aws_sns';
|
|
24
|
+
export type MessagingTransport = EmailTransport | SmsTransport;
|
|
25
|
+
/** Sender number or ID for an SMS provider. `from_address` on the request takes precedence. */
|
|
26
|
+
interface SmsFrom {
|
|
27
|
+
/** Sender number or ID for this provider. Optional; `from_address` on the request takes precedence. */
|
|
28
|
+
from?: string;
|
|
22
29
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
/** Resend. */
|
|
31
|
+
export interface ResendConfig {
|
|
32
|
+
/** Resend API key (`re_…`). Required on first setup. Write-only: never returned. */
|
|
33
|
+
api_key: string;
|
|
34
|
+
}
|
|
35
|
+
/** Brevo. */
|
|
36
|
+
export interface BrevoConfig {
|
|
37
|
+
/** Brevo API key (`xkeysib-…`). Required on first setup. Write-only: never returned. */
|
|
38
|
+
api_key: string;
|
|
39
|
+
}
|
|
40
|
+
/** Mailgun. */
|
|
41
|
+
export interface MailgunConfig {
|
|
42
|
+
/** Mailgun private API key. Required on first setup. Write-only: never returned. */
|
|
43
|
+
api_key: string;
|
|
44
|
+
/** Your Mailgun sending domain, e.g. `mg.example.com`. Required on first setup. */
|
|
45
|
+
domain: string;
|
|
46
|
+
/** Mailgun region. Default `us`. */
|
|
47
|
+
region?: 'us' | 'eu';
|
|
48
|
+
}
|
|
49
|
+
/** Amazon SES. */
|
|
50
|
+
export interface SesConfig {
|
|
51
|
+
/** AWS region, e.g. `us-east-1`. Required on first setup. */
|
|
52
|
+
region: string;
|
|
53
|
+
/** IAM access key ID. Required on first setup. Write-only: never returned. */
|
|
54
|
+
access_key_id: string;
|
|
55
|
+
/** IAM secret access key. Required on first setup. Write-only: never returned. */
|
|
56
|
+
secret_access_key: string;
|
|
57
|
+
/** STS session token, only for temporary credentials. Write-only: never returned. */
|
|
58
|
+
session_token?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Any SMTP server. */
|
|
61
|
+
export interface SmtpConfig {
|
|
62
|
+
/** SMTP server hostname, e.g. `smtp.example.com`. Required on first setup. */
|
|
63
|
+
host: string;
|
|
64
|
+
/** SMTP port (1-65535). Default 587. */
|
|
65
|
+
port?: number;
|
|
66
|
+
/** Use implicit TLS. Default: `true` on port 465, otherwise STARTTLS. */
|
|
67
|
+
secure?: boolean;
|
|
68
|
+
/** SMTP username, if the server requires authentication. */
|
|
69
|
+
username?: string;
|
|
70
|
+
/** SMTP password or app password. Write-only: never returned. */
|
|
71
|
+
password?: string;
|
|
72
|
+
}
|
|
73
|
+
/** Twilio. */
|
|
74
|
+
export interface TwilioConfig extends SmsFrom {
|
|
75
|
+
/** Twilio Account SID (`AC…`). Required on first setup. */
|
|
76
|
+
account_sid: string;
|
|
77
|
+
/** Twilio auth token. Required on first setup. Write-only: never returned. */
|
|
78
|
+
auth_token: string;
|
|
79
|
+
/** WhatsApp-enabled sender number, for the WhatsApp channel. */
|
|
80
|
+
whatsapp_from?: string;
|
|
81
|
+
/** Voice-capable number, for the voice channel. */
|
|
82
|
+
voice_from?: string;
|
|
83
|
+
}
|
|
84
|
+
/** Vonage. */
|
|
85
|
+
export interface VonageConfig extends SmsFrom {
|
|
86
|
+
/** Vonage API key. Required on first setup. */
|
|
87
|
+
api_key: string;
|
|
88
|
+
/** Vonage API secret. Required on first setup. Write-only: never returned. */
|
|
89
|
+
api_secret: string;
|
|
90
|
+
}
|
|
91
|
+
/** MessageBird (Bird). */
|
|
92
|
+
export interface MessagebirdConfig extends SmsFrom {
|
|
93
|
+
/** MessageBird (Bird) access key. Required on first setup. Write-only: never returned. */
|
|
94
|
+
access_key: string;
|
|
95
|
+
}
|
|
96
|
+
/** Plivo. */
|
|
97
|
+
export interface PlivoConfig extends SmsFrom {
|
|
98
|
+
/** Plivo Auth ID. Required on first setup. */
|
|
99
|
+
auth_id: string;
|
|
100
|
+
/** Plivo auth token. Required on first setup. Write-only: never returned. */
|
|
101
|
+
auth_token: string;
|
|
102
|
+
}
|
|
103
|
+
/** Telnyx. */
|
|
104
|
+
export interface TelnyxConfig extends SmsFrom {
|
|
105
|
+
/** Telnyx API key. Required on first setup. Write-only: never returned. */
|
|
106
|
+
api_key: string;
|
|
107
|
+
}
|
|
108
|
+
/** Sinch. */
|
|
109
|
+
export interface SinchConfig extends SmsFrom {
|
|
110
|
+
/** Sinch service plan ID. Required on first setup. */
|
|
111
|
+
service_plan_id: string;
|
|
112
|
+
/** Sinch API token. Required on first setup. Write-only: never returned. */
|
|
113
|
+
api_token: string;
|
|
114
|
+
/** Sinch API region, a short lowercase code such as `us` or `eu`. Default `us`. */
|
|
115
|
+
region?: string;
|
|
116
|
+
}
|
|
117
|
+
/** Infobip. */
|
|
118
|
+
export interface InfobipConfig extends SmsFrom {
|
|
119
|
+
/** Your Infobip base URL, e.g. `https://xxxxx.api.infobip.com`. Must be https. Required on first setup. */
|
|
120
|
+
base_url: string;
|
|
121
|
+
/** Infobip API key. Required on first setup. Write-only: never returned. */
|
|
122
|
+
api_key: string;
|
|
123
|
+
}
|
|
124
|
+
/** ClickSend. */
|
|
125
|
+
export interface ClicksendConfig extends SmsFrom {
|
|
126
|
+
/** ClickSend username (your login email). Required on first setup. */
|
|
127
|
+
username: string;
|
|
128
|
+
/** ClickSend API key. Required on first setup. Write-only: never returned. */
|
|
129
|
+
api_key: string;
|
|
130
|
+
}
|
|
131
|
+
/** Bandwidth. */
|
|
132
|
+
export interface BandwidthConfig extends SmsFrom {
|
|
133
|
+
/** Bandwidth account ID. Required on first setup. */
|
|
134
|
+
account_id: string;
|
|
135
|
+
/** Bandwidth messaging application ID. Required on first setup. */
|
|
136
|
+
application_id: string;
|
|
137
|
+
/** Bandwidth API username. Required on first setup. */
|
|
138
|
+
username: string;
|
|
139
|
+
/** Bandwidth API password. Required on first setup. Write-only: never returned. */
|
|
140
|
+
password: string;
|
|
141
|
+
}
|
|
142
|
+
/** Amazon SNS. */
|
|
143
|
+
export interface AwsSnsConfig extends SmsFrom {
|
|
144
|
+
/** AWS region, e.g. `us-east-1`. Required on first setup. */
|
|
145
|
+
region: string;
|
|
146
|
+
/** IAM access key ID. Required on first setup. */
|
|
147
|
+
access_key_id: string;
|
|
148
|
+
/** IAM secret access key. Required on first setup. Write-only: never returned. */
|
|
149
|
+
secret_access_key: string;
|
|
150
|
+
/** STS session token, only for temporary credentials. Write-only: never returned. */
|
|
151
|
+
session_token?: string;
|
|
152
|
+
}
|
|
153
|
+
/** The `config` shape for each transport, keyed by transport. */
|
|
154
|
+
export interface MessagingTransportConfigs {
|
|
155
|
+
resend: ResendConfig;
|
|
156
|
+
ses: SesConfig;
|
|
157
|
+
smtp: SmtpConfig;
|
|
158
|
+
brevo: BrevoConfig;
|
|
159
|
+
mailgun: MailgunConfig;
|
|
160
|
+
twilio: TwilioConfig;
|
|
161
|
+
vonage: VonageConfig;
|
|
162
|
+
messagebird: MessagebirdConfig;
|
|
163
|
+
plivo: PlivoConfig;
|
|
164
|
+
telnyx: TelnyxConfig;
|
|
165
|
+
sinch: SinchConfig;
|
|
166
|
+
infobip: InfobipConfig;
|
|
167
|
+
clicksend: ClicksendConfig;
|
|
168
|
+
bandwidth: BandwidthConfig;
|
|
169
|
+
aws_sns: AwsSnsConfig;
|
|
27
170
|
}
|
|
171
|
+
/** The write-only (secret) keys of each transport — never present in a response. */
|
|
172
|
+
export interface MessagingSecretKeys {
|
|
173
|
+
resend: 'api_key';
|
|
174
|
+
ses: 'access_key_id' | 'secret_access_key' | 'session_token';
|
|
175
|
+
smtp: 'password';
|
|
176
|
+
brevo: 'api_key';
|
|
177
|
+
mailgun: 'api_key';
|
|
178
|
+
twilio: 'auth_token';
|
|
179
|
+
vonage: 'api_secret';
|
|
180
|
+
messagebird: 'access_key';
|
|
181
|
+
plivo: 'auth_token';
|
|
182
|
+
telnyx: 'api_key';
|
|
183
|
+
sinch: 'api_token';
|
|
184
|
+
infobip: 'api_key';
|
|
185
|
+
clicksend: 'api_key';
|
|
186
|
+
bandwidth: 'password';
|
|
187
|
+
aws_sns: 'secret_access_key' | 'session_token';
|
|
188
|
+
}
|
|
189
|
+
interface ProviderBodyBase<T extends MessagingTransport> {
|
|
190
|
+
transport: T;
|
|
191
|
+
/**
|
|
192
|
+
* Email: the From address, e.g. `"Acme <no-reply@acme.com>"` — a sender your
|
|
193
|
+
* provider accepts. SMS: the sender number in E.164 format, e.g. `+15551234567`.
|
|
194
|
+
*/
|
|
195
|
+
from_address?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* First setup of transport `T` (or a switch to it): `config` carries every
|
|
199
|
+
* required key.
|
|
200
|
+
*/
|
|
201
|
+
export interface MessagingProviderSetup<T extends MessagingTransport> extends ProviderBodyBase<T> {
|
|
202
|
+
config: MessagingTransportConfigs[T];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* An update of the transport already configured on the channel: every `config`
|
|
206
|
+
* key is optional. An omitted (or `''`) key keeps its stored value — including a
|
|
207
|
+
* stored secret.
|
|
208
|
+
*/
|
|
209
|
+
export interface MessagingProviderUpdate<T extends MessagingTransport> extends ProviderBodyBase<T> {
|
|
210
|
+
config?: Partial<MessagingTransportConfigs[T]>;
|
|
211
|
+
}
|
|
212
|
+
/** Body for `messaging.setEmail` — discriminated by `transport`. */
|
|
213
|
+
export type EmailProviderInput = {
|
|
214
|
+
[T in EmailTransport]: MessagingProviderSetup<T> | MessagingProviderUpdate<T>;
|
|
215
|
+
}[EmailTransport];
|
|
216
|
+
/** Body for `messaging.setSms` — discriminated by `transport`. */
|
|
217
|
+
export type SmsProviderInput = {
|
|
218
|
+
[T in SmsTransport]: MessagingProviderSetup<T> | MessagingProviderUpdate<T>;
|
|
219
|
+
}[SmsTransport];
|
|
220
|
+
/** First-setup body for the email channel. Use with `satisfies` to require every required key. */
|
|
221
|
+
export type EmailProviderSetup = {
|
|
222
|
+
[T in EmailTransport]: MessagingProviderSetup<T>;
|
|
223
|
+
}[EmailTransport];
|
|
224
|
+
/** First-setup body for the SMS channel. Use with `satisfies` to require every required key. */
|
|
225
|
+
export type SmsProviderSetup = {
|
|
226
|
+
[T in SmsTransport]: MessagingProviderSetup<T>;
|
|
227
|
+
}[SmsTransport];
|
|
228
|
+
/**
|
|
229
|
+
* @deprecated The untyped body accepted before per-transport typing. Use
|
|
230
|
+
* {@link EmailProviderInput} / {@link SmsProviderInput} instead; the API refuses
|
|
231
|
+
* any `config` key the transport does not use.
|
|
232
|
+
*/
|
|
28
233
|
export interface MessagingProviderInput {
|
|
29
234
|
/** The transport, e.g. `resend`, `ses`, `smtp` (email) or `twilio` (sms). */
|
|
30
235
|
transport: string;
|
|
@@ -32,6 +237,42 @@ export interface MessagingProviderInput {
|
|
|
32
237
|
/** Transport config; carries the write-only secret keys on write. */
|
|
33
238
|
config?: Record<string, unknown>;
|
|
34
239
|
}
|
|
240
|
+
/** The non-secret config keys of transport `T`. */
|
|
241
|
+
type PublicConfigKey<T extends MessagingTransport> = Exclude<keyof MessagingTransportConfigs[T], MessagingSecretKeys[T]>;
|
|
242
|
+
/**
|
|
243
|
+
* A configured provider as returned by the API. `config` holds the non-secret
|
|
244
|
+
* settings only (values come back as strings, e.g. `port: "587"`); secrets are
|
|
245
|
+
* never returned — `secrets_set` says which ones are stored.
|
|
246
|
+
*/
|
|
247
|
+
export interface MessagingProviderOf<C extends 'email' | 'sms', T extends MessagingTransport> {
|
|
248
|
+
object: 'messaging_provider';
|
|
249
|
+
channel: C;
|
|
250
|
+
transport: T;
|
|
251
|
+
from_address: string | null;
|
|
252
|
+
status: string;
|
|
253
|
+
/** Non-secret config only — secret values are never returned. */
|
|
254
|
+
config: {
|
|
255
|
+
[K in PublicConfigKey<T>]?: string;
|
|
256
|
+
};
|
|
257
|
+
/** For each secret key of this transport: whether a value is stored. Never the value. */
|
|
258
|
+
secrets_set: {
|
|
259
|
+
[K in MessagingSecretKeys[T]]: boolean;
|
|
260
|
+
};
|
|
261
|
+
updated_at: number;
|
|
262
|
+
}
|
|
263
|
+
export type EmailProvider = {
|
|
264
|
+
[T in EmailTransport]: MessagingProviderOf<'email', T>;
|
|
265
|
+
}[EmailTransport];
|
|
266
|
+
export type SmsProvider = {
|
|
267
|
+
[T in SmsTransport]: MessagingProviderOf<'sms', T>;
|
|
268
|
+
}[SmsTransport];
|
|
269
|
+
/** Either channel's provider. Narrow on `transport` (or `channel`) to read its config. */
|
|
270
|
+
export type MessagingProvider = EmailProvider | SmsProvider;
|
|
271
|
+
export interface MessagingProviders {
|
|
272
|
+
object: 'messaging_providers';
|
|
273
|
+
email: EmailProvider | null;
|
|
274
|
+
sms: SmsProvider | null;
|
|
275
|
+
}
|
|
35
276
|
export interface MessagingTestResult {
|
|
36
277
|
object: 'messaging_test';
|
|
37
278
|
channel: string;
|
|
@@ -43,14 +284,39 @@ export interface DeletedMessagingProvider {
|
|
|
43
284
|
channel: string;
|
|
44
285
|
deleted: true;
|
|
45
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* The deprecated untyped body, accepted only when `transport` is a plain
|
|
289
|
+
* `string` (not a known literal) — so a typed literal with a wrong key still
|
|
290
|
+
* fails to compile instead of falling through to the legacy overload.
|
|
291
|
+
*/
|
|
292
|
+
type LegacyInput<T extends string> = Omit<MessagingProviderInput, 'transport'> & {
|
|
293
|
+
transport: T;
|
|
294
|
+
} & (string extends T ? unknown : never);
|
|
46
295
|
export declare function messagingResource(request: RequestFn): {
|
|
47
296
|
/** The instance's configured email and SMS providers, secrets omitted. */
|
|
48
297
|
get(): Promise<MessagingProviders>;
|
|
49
|
-
|
|
50
|
-
|
|
298
|
+
/**
|
|
299
|
+
* Configure (or update) the email provider. `config` keys are checked per
|
|
300
|
+
* `transport`; on an update of the same transport, omitted keys — including
|
|
301
|
+
* secrets — keep their stored values.
|
|
302
|
+
*/
|
|
303
|
+
setEmail: {
|
|
304
|
+
(body: EmailProviderInput): Promise<EmailProvider>;
|
|
305
|
+
<T extends string>(body: LegacyInput<T>): Promise<MessagingProvider>;
|
|
306
|
+
};
|
|
307
|
+
/**
|
|
308
|
+
* Configure (or update) the SMS provider. `config` keys are checked per
|
|
309
|
+
* `transport`; on an update of the same transport, omitted keys — including
|
|
310
|
+
* secrets — keep their stored values.
|
|
311
|
+
*/
|
|
312
|
+
setSms: {
|
|
313
|
+
(body: SmsProviderInput): Promise<SmsProvider>;
|
|
314
|
+
<T extends string>(body: LegacyInput<T>): Promise<MessagingProvider>;
|
|
315
|
+
};
|
|
51
316
|
deleteChannel(channel: "email" | "sms"): Promise<DeletedMessagingProvider>;
|
|
52
317
|
/** Send a fixed, clearly-marked test message through the channel's provider. */
|
|
53
318
|
test(channel: "email" | "sms", body: {
|
|
54
319
|
to: string;
|
|
55
320
|
}): Promise<MessagingTestResult>;
|
|
56
321
|
};
|
|
322
|
+
export {};
|
package/dist/client/messaging.js
CHANGED
|
@@ -3,17 +3,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.messagingResource = messagingResource;
|
|
4
4
|
const request_1 = require("./request");
|
|
5
5
|
function messagingResource(request) {
|
|
6
|
+
function setEmail(body) {
|
|
7
|
+
return request({ method: 'PUT', path: '/v1/messaging_providers/email', body });
|
|
8
|
+
}
|
|
9
|
+
function setSms(body) {
|
|
10
|
+
return request({ method: 'PUT', path: '/v1/messaging_providers/sms', body });
|
|
11
|
+
}
|
|
6
12
|
return {
|
|
7
13
|
/** The instance's configured email and SMS providers, secrets omitted. */
|
|
8
14
|
get() {
|
|
9
15
|
return request({ method: 'GET', path: '/v1/messaging_providers' });
|
|
10
16
|
},
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Configure (or update) the email provider. `config` keys are checked per
|
|
19
|
+
* `transport`; on an update of the same transport, omitted keys — including
|
|
20
|
+
* secrets — keep their stored values.
|
|
21
|
+
*/
|
|
22
|
+
setEmail,
|
|
23
|
+
/**
|
|
24
|
+
* Configure (or update) the SMS provider. `config` keys are checked per
|
|
25
|
+
* `transport`; on an update of the same transport, omitted keys — including
|
|
26
|
+
* secrets — keep their stored values.
|
|
27
|
+
*/
|
|
28
|
+
setSms,
|
|
17
29
|
deleteChannel(channel) {
|
|
18
30
|
return request({ method: 'DELETE', path: `/v1/messaging_providers/${(0, request_1.enc)(channel)}` });
|
|
19
31
|
},
|
|
@@ -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":";;AAsVA,8CA4CC;AAlYD,uCAAgD;AAsVhD,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,aAAa,CAAC,OAAwB;YACpC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,2BAA2B,IAAA,aAAG,EAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC discovery of an instance's JWKS URL, so `new AtlasBackend({ issuer })`
|
|
3
|
+
* works without a `jwksUrl`.
|
|
4
|
+
*
|
|
5
|
+
* Where the document lives:
|
|
6
|
+
* - an instance with its own frontend API host (every instance created from
|
|
7
|
+
* the dashboard): `${issuer}/.well-known/openid-configuration`;
|
|
8
|
+
* - an instance on the SHARED host: its tokens carry the shared issuer, and the
|
|
9
|
+
* shared host's root discovery document describes a different instance's key
|
|
10
|
+
* set. Such an instance must name itself (`instanceId`, or a `publishableKey`
|
|
11
|
+
* it is derived from) so discovery uses the per-instance document at
|
|
12
|
+
* `${issuer}/instances/${instanceId}/.well-known/openid-configuration`.
|
|
13
|
+
*
|
|
14
|
+
* Caching mirrors the JWKS cache: the discovered URL is reused for the JWKS TTL
|
|
15
|
+
* (an hour), a failed refresh keeps serving the last good URL, and a failing
|
|
16
|
+
* endpoint is retried at most once a minute — so a broken or hostile discovery
|
|
17
|
+
* endpoint cannot turn verification traffic into outbound request floods.
|
|
18
|
+
*/
|
|
19
|
+
export declare class DiscoveryError extends Error {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
export interface JwksDiscoveryDeps {
|
|
23
|
+
/** The `iss` tokens carry. The discovery document's `issuer` must equal it. */
|
|
24
|
+
issuer: string;
|
|
25
|
+
/** Per-instance discovery for shared-host instances. */
|
|
26
|
+
instanceId?: string;
|
|
27
|
+
fetchImpl?: typeof fetch;
|
|
28
|
+
now?: () => number;
|
|
29
|
+
ttlMs?: number;
|
|
30
|
+
refetchIntervalMs?: number;
|
|
31
|
+
}
|
|
32
|
+
/** The instance id inside a publishable key (`pk_live_ins_…` / `pk_test_ins_…`), if it has one. */
|
|
33
|
+
export declare function instanceIdFromPublishableKey(publishableKey: string): string | undefined;
|
|
34
|
+
/** The discovery document URL for an issuer (and optional instance id). */
|
|
35
|
+
export declare function discoveryUrlFor(issuer: string, instanceId?: string): string;
|
|
36
|
+
export declare class JwksDiscovery {
|
|
37
|
+
private readonly deps;
|
|
38
|
+
readonly url: string;
|
|
39
|
+
private cachedUri;
|
|
40
|
+
private fetchedAt;
|
|
41
|
+
private lastAttemptAt;
|
|
42
|
+
private lastError;
|
|
43
|
+
private inflight;
|
|
44
|
+
constructor(deps: JwksDiscoveryDeps);
|
|
45
|
+
private get now();
|
|
46
|
+
/** The JWKS URL, from cache when fresh. Throws {@link DiscoveryError} when none can be had. */
|
|
47
|
+
jwksUri(): Promise<string>;
|
|
48
|
+
private fetchUri;
|
|
49
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JwksDiscovery = exports.DiscoveryError = void 0;
|
|
4
|
+
exports.instanceIdFromPublishableKey = instanceIdFromPublishableKey;
|
|
5
|
+
exports.discoveryUrlFor = discoveryUrlFor;
|
|
6
|
+
const jwks_cache_1 = require("./jwks-cache");
|
|
7
|
+
/**
|
|
8
|
+
* OIDC discovery of an instance's JWKS URL, so `new AtlasBackend({ issuer })`
|
|
9
|
+
* works without a `jwksUrl`.
|
|
10
|
+
*
|
|
11
|
+
* Where the document lives:
|
|
12
|
+
* - an instance with its own frontend API host (every instance created from
|
|
13
|
+
* the dashboard): `${issuer}/.well-known/openid-configuration`;
|
|
14
|
+
* - an instance on the SHARED host: its tokens carry the shared issuer, and the
|
|
15
|
+
* shared host's root discovery document describes a different instance's key
|
|
16
|
+
* set. Such an instance must name itself (`instanceId`, or a `publishableKey`
|
|
17
|
+
* it is derived from) so discovery uses the per-instance document at
|
|
18
|
+
* `${issuer}/instances/${instanceId}/.well-known/openid-configuration`.
|
|
19
|
+
*
|
|
20
|
+
* Caching mirrors the JWKS cache: the discovered URL is reused for the JWKS TTL
|
|
21
|
+
* (an hour), a failed refresh keeps serving the last good URL, and a failing
|
|
22
|
+
* endpoint is retried at most once a minute — so a broken or hostile discovery
|
|
23
|
+
* endpoint cannot turn verification traffic into outbound request floods.
|
|
24
|
+
*/
|
|
25
|
+
class DiscoveryError extends Error {
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'DiscoveryError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.DiscoveryError = DiscoveryError;
|
|
32
|
+
const stripSlash = (value) => value.replace(/\/+$/, '');
|
|
33
|
+
/** The instance id inside a publishable key (`pk_live_ins_…` / `pk_test_ins_…`), if it has one. */
|
|
34
|
+
function instanceIdFromPublishableKey(publishableKey) {
|
|
35
|
+
const match = /^pk_(?:live|test)_(ins_[A-Za-z0-9]+)$/.exec(publishableKey.trim());
|
|
36
|
+
return match?.[1];
|
|
37
|
+
}
|
|
38
|
+
/** The discovery document URL for an issuer (and optional instance id). */
|
|
39
|
+
function discoveryUrlFor(issuer, instanceId) {
|
|
40
|
+
const base = stripSlash(issuer);
|
|
41
|
+
return instanceId
|
|
42
|
+
? `${base}/instances/${encodeURIComponent(instanceId)}/.well-known/openid-configuration`
|
|
43
|
+
: `${base}/.well-known/openid-configuration`;
|
|
44
|
+
}
|
|
45
|
+
function isLoopback(hostname) {
|
|
46
|
+
return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';
|
|
47
|
+
}
|
|
48
|
+
class JwksDiscovery {
|
|
49
|
+
deps;
|
|
50
|
+
url;
|
|
51
|
+
cachedUri = null;
|
|
52
|
+
fetchedAt = 0;
|
|
53
|
+
lastAttemptAt = 0;
|
|
54
|
+
lastError = null;
|
|
55
|
+
inflight = null;
|
|
56
|
+
constructor(deps) {
|
|
57
|
+
this.deps = deps;
|
|
58
|
+
this.url = discoveryUrlFor(deps.issuer, deps.instanceId);
|
|
59
|
+
}
|
|
60
|
+
get now() {
|
|
61
|
+
return (this.deps.now ?? Date.now)();
|
|
62
|
+
}
|
|
63
|
+
/** The JWKS URL, from cache when fresh. Throws {@link DiscoveryError} when none can be had. */
|
|
64
|
+
async jwksUri() {
|
|
65
|
+
const now = this.now;
|
|
66
|
+
const ttl = this.deps.ttlMs ?? jwks_cache_1.DEFAULT_TTL_MS;
|
|
67
|
+
const interval = this.deps.refetchIntervalMs ?? jwks_cache_1.REFETCH_INTERVAL_MS;
|
|
68
|
+
if (this.cachedUri && now - this.fetchedAt < ttl)
|
|
69
|
+
return this.cachedUri;
|
|
70
|
+
// Throttle: inside the retry window, answer from what we have (or the last error).
|
|
71
|
+
if (this.lastAttemptAt && now - this.lastAttemptAt < interval) {
|
|
72
|
+
if (this.cachedUri)
|
|
73
|
+
return this.cachedUri;
|
|
74
|
+
if (this.lastError)
|
|
75
|
+
throw this.lastError;
|
|
76
|
+
}
|
|
77
|
+
if (this.inflight)
|
|
78
|
+
return this.inflight;
|
|
79
|
+
this.lastAttemptAt = now;
|
|
80
|
+
this.inflight = this.fetchUri()
|
|
81
|
+
.then((uri) => {
|
|
82
|
+
this.cachedUri = uri;
|
|
83
|
+
this.fetchedAt = now;
|
|
84
|
+
this.lastError = null;
|
|
85
|
+
return uri;
|
|
86
|
+
})
|
|
87
|
+
.catch((error) => {
|
|
88
|
+
this.lastError =
|
|
89
|
+
error instanceof DiscoveryError
|
|
90
|
+
? error
|
|
91
|
+
: new DiscoveryError(`OIDC discovery at ${this.url} failed: ${error?.message ?? String(error)}`);
|
|
92
|
+
// Keep serving the last good URL through a discovery outage.
|
|
93
|
+
if (this.cachedUri)
|
|
94
|
+
return this.cachedUri;
|
|
95
|
+
throw this.lastError;
|
|
96
|
+
})
|
|
97
|
+
.finally(() => {
|
|
98
|
+
this.inflight = null;
|
|
99
|
+
});
|
|
100
|
+
return this.inflight;
|
|
101
|
+
}
|
|
102
|
+
async fetchUri() {
|
|
103
|
+
const fail = (why) => new DiscoveryError(`OIDC discovery at ${this.url} failed: ${why}. Pass \`jwksUrl\` explicitly` +
|
|
104
|
+
(this.deps.instanceId
|
|
105
|
+
? '.'
|
|
106
|
+
: ', or — for an instance without its own frontend API domain — pass `instanceId` (or `publishableKey`).'));
|
|
107
|
+
const response = await (this.deps.fetchImpl ?? fetch)(this.url, {
|
|
108
|
+
headers: { accept: 'application/json' },
|
|
109
|
+
});
|
|
110
|
+
if (!response.ok)
|
|
111
|
+
throw fail(`HTTP ${response.status}`);
|
|
112
|
+
let body;
|
|
113
|
+
try {
|
|
114
|
+
body = await response.json();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
throw fail('the response is not JSON');
|
|
118
|
+
}
|
|
119
|
+
const doc = body;
|
|
120
|
+
if (!doc || typeof doc !== 'object')
|
|
121
|
+
throw fail('the response is not a discovery document');
|
|
122
|
+
// OIDC Discovery §4.3: the document's issuer MUST match the issuer it was
|
|
123
|
+
// fetched for — otherwise its keys belong to someone else.
|
|
124
|
+
if (typeof doc.issuer !== 'string' || stripSlash(doc.issuer) !== stripSlash(this.deps.issuer)) {
|
|
125
|
+
throw fail(`its issuer (${String(doc.issuer)}) does not match the configured issuer (${this.deps.issuer})`);
|
|
126
|
+
}
|
|
127
|
+
if (typeof doc.jwks_uri !== 'string')
|
|
128
|
+
throw fail('it has no jwks_uri');
|
|
129
|
+
let jwks;
|
|
130
|
+
try {
|
|
131
|
+
jwks = new URL(doc.jwks_uri);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
throw fail('its jwks_uri is not an absolute URL');
|
|
135
|
+
}
|
|
136
|
+
if (jwks.protocol !== 'https:' && !(jwks.protocol === 'http:' && isLoopback(jwks.hostname))) {
|
|
137
|
+
throw fail('its jwks_uri is not https');
|
|
138
|
+
}
|
|
139
|
+
return jwks.toString();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.JwksDiscovery = JwksDiscovery;
|
|
143
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './jwks-cache';
|
|
2
|
+
export { DiscoveryError, JwksDiscovery, discoveryUrlFor, instanceIdFromPublishableKey } from './discovery';
|
|
2
3
|
export * from './verify';
|
|
3
4
|
export * from './handshake';
|
|
4
5
|
export * from './webhooks';
|
|
@@ -7,3 +8,7 @@ export type { AtlasClient } from './client';
|
|
|
7
8
|
export * from './client';
|
|
8
9
|
export { createTestIssuer } from './testing';
|
|
9
10
|
export type { TestIssuer, CreateTestIssuerOptions } from './testing';
|
|
11
|
+
export { verifyPCActn } from './pca/verify';
|
|
12
|
+
export type { PcaVerdict, PcaContext, VerifyPCActnOptions } from './pca/verify';
|
|
13
|
+
export { requirePCA, defaultExtract, memoryPcaStore } from './pca/require-pca';
|
|
14
|
+
export type { RequirePcaOptions, PcaGuardResult, PcaRequestLike, PcaStateStore } from './pca/require-pca';
|
package/dist/index.js
CHANGED
|
@@ -14,9 +14,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.createTestIssuer = exports.createAtlasClient = void 0;
|
|
17
|
+
exports.memoryPcaStore = exports.defaultExtract = exports.requirePCA = exports.verifyPCActn = exports.createTestIssuer = exports.createAtlasClient = exports.instanceIdFromPublishableKey = exports.discoveryUrlFor = exports.JwksDiscovery = exports.DiscoveryError = void 0;
|
|
18
18
|
// §7.3 token verification — the original surface, unchanged.
|
|
19
19
|
__exportStar(require("./jwks-cache"), exports);
|
|
20
|
+
// OIDC discovery of the JWKS URL when only `issuer` is configured.
|
|
21
|
+
var discovery_1 = require("./discovery");
|
|
22
|
+
Object.defineProperty(exports, "DiscoveryError", { enumerable: true, get: function () { return discovery_1.DiscoveryError; } });
|
|
23
|
+
Object.defineProperty(exports, "JwksDiscovery", { enumerable: true, get: function () { return discovery_1.JwksDiscovery; } });
|
|
24
|
+
Object.defineProperty(exports, "discoveryUrlFor", { enumerable: true, get: function () { return discovery_1.discoveryUrlFor; } });
|
|
25
|
+
Object.defineProperty(exports, "instanceIdFromPublishableKey", { enumerable: true, get: function () { return discovery_1.instanceIdFromPublishableKey; } });
|
|
20
26
|
__exportStar(require("./verify"), exports);
|
|
21
27
|
__exportStar(require("./handshake"), exports);
|
|
22
28
|
// §12.2 inbound webhook verification for consumers.
|
|
@@ -30,4 +36,12 @@ __exportStar(require("./client"), exports);
|
|
|
30
36
|
// Its own module, so it never sits on the hot verification path.
|
|
31
37
|
var testing_1 = require("./testing");
|
|
32
38
|
Object.defineProperty(exports, "createTestIssuer", { enumerable: true, get: function () { return testing_1.createTestIssuer; } });
|
|
39
|
+
// Proof-Carrying Authority (agentic auth): offline verifier + framework-agnostic guard,
|
|
40
|
+
// beside the session-token verifier above.
|
|
41
|
+
var verify_1 = require("./pca/verify");
|
|
42
|
+
Object.defineProperty(exports, "verifyPCActn", { enumerable: true, get: function () { return verify_1.verifyPCActn; } });
|
|
43
|
+
var require_pca_1 = require("./pca/require-pca");
|
|
44
|
+
Object.defineProperty(exports, "requirePCA", { enumerable: true, get: function () { return require_pca_1.requirePCA; } });
|
|
45
|
+
Object.defineProperty(exports, "defaultExtract", { enumerable: true, get: function () { return require_pca_1.defaultExtract; } });
|
|
46
|
+
Object.defineProperty(exports, "memoryPcaStore", { enumerable: true, get: function () { return require_pca_1.memoryPcaStore; } });
|
|
33
47
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,2CAAyB;AACzB,8CAA4B;AAE5B,oDAAoD;AACpD,6CAA2B;AAE3B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,mEAAmE;AACnE,yCAA2G;AAAlG,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,yHAAA,4BAA4B,OAAA;AACrF,2CAAyB;AACzB,8CAA4B;AAE5B,oDAAoD;AACpD,6CAA2B;AAE3B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AAGzB,wFAAwF;AACxF,2CAA2C;AAC3C,uCAA4C;AAAnC,sGAAA,YAAY,OAAA;AAErB,iDAA+E;AAAtE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA"}
|
package/dist/jwks-cache.d.ts
CHANGED
|
@@ -34,6 +34,12 @@ export interface JwksCacheDeps {
|
|
|
34
34
|
* when both are given the static set wins and no network call is ever made.
|
|
35
35
|
*/
|
|
36
36
|
staticJwks?: Jwks;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the JWKS URL lazily (OIDC discovery) when no fixed `url` is given.
|
|
39
|
+
* Called on each fetch attempt; it does its own caching. A rejection is
|
|
40
|
+
* recorded as {@link JwksCache.lastError} and treated like a failed fetch.
|
|
41
|
+
*/
|
|
42
|
+
resolveUrl?: () => Promise<string>;
|
|
37
43
|
fetchImpl?: typeof fetch;
|
|
38
44
|
now?: () => number;
|
|
39
45
|
ttlMs?: number;
|
|
@@ -47,6 +53,8 @@ export declare class JwksCache {
|
|
|
47
53
|
private lastAttemptAt;
|
|
48
54
|
/** Exposed so a caller can assert the rate limit actually bit. */
|
|
49
55
|
lastOutcome: FetchOutcome;
|
|
56
|
+
/** Why the last attempt produced no keys (e.g. a discovery failure), for diagnostics. */
|
|
57
|
+
lastError: string | null;
|
|
50
58
|
constructor(deps: JwksCacheDeps);
|
|
51
59
|
private get now();
|
|
52
60
|
private has;
|