@hyper.authio/testing 0.1.1 → 0.7.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/README.md +18 -4
- package/dist/index.cjs +306 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -7
- package/dist/index.d.ts +134 -7
- package/dist/index.js +308 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import { JWK } from 'jose';
|
|
2
2
|
import { AuthioClock } from '@hyper.authio/client';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* How the fake encrypts what it issues to a client, as Authio does once the client registered an encryption key.
|
|
6
|
+
*/
|
|
7
|
+
interface FakeAuthioClientEncryption {
|
|
8
|
+
/** The client's public encryption key (RSA). */
|
|
9
|
+
key: JWK;
|
|
10
|
+
/** Defaults to `RSA-OAEP-256`. */
|
|
11
|
+
algorithm?: "RSA-OAEP" | "RSA-OAEP-256";
|
|
12
|
+
/** Defaults to `A256CBC-HS512`. */
|
|
13
|
+
encryptionMethod?: "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512";
|
|
14
|
+
/** Encrypts the client's access tokens (nested JWT). */
|
|
15
|
+
accessTokens?: boolean;
|
|
16
|
+
/** Encrypts the client's ID tokens. Defaults to `true`. */
|
|
17
|
+
idTokens?: boolean;
|
|
18
|
+
/** Encrypts UserInfo answered as a JWT. Defaults to `true`. */
|
|
19
|
+
userInfo?: boolean;
|
|
20
|
+
/** Encrypts back-channel logout tokens. */
|
|
21
|
+
logoutTokens?: boolean;
|
|
22
|
+
}
|
|
4
23
|
/**
|
|
5
24
|
* A client registered in the fake.
|
|
6
25
|
*/
|
|
@@ -16,6 +35,14 @@ interface FakeAuthioClient {
|
|
|
16
35
|
claims?: Record<string, unknown>;
|
|
17
36
|
/** The client this one's tokens are introspectable by, besides itself (a resource server's introspection client). */
|
|
18
37
|
introspectionClients?: string[];
|
|
38
|
+
/** The redirect URIs the authorization endpoint accepts. Any when absent. */
|
|
39
|
+
redirectUris?: string[];
|
|
40
|
+
/** The post-logout redirect URIs the end-session endpoint accepts. Any when absent. */
|
|
41
|
+
postLogoutRedirectUris?: string[];
|
|
42
|
+
/** Where back-channel logout tokens are posted when a session of the client ends. */
|
|
43
|
+
backchannelLogoutUri?: string;
|
|
44
|
+
/** Encrypts what is issued to the client. */
|
|
45
|
+
encryption?: FakeAuthioClientEncryption;
|
|
19
46
|
}
|
|
20
47
|
/**
|
|
21
48
|
* A person the fake knows, for the password grant, authorization codes and UserInfo.
|
|
@@ -28,6 +55,23 @@ interface FakeAuthioUser {
|
|
|
28
55
|
claims?: Record<string, unknown>;
|
|
29
56
|
/** What UserInfo answers besides `sub`. */
|
|
30
57
|
userInfo?: Record<string, unknown>;
|
|
58
|
+
/** The sign-in's methods. Defaults to `["pwd"]`. */
|
|
59
|
+
amr?: string[];
|
|
60
|
+
/** The sign-in's level. Defaults to `1`, or the `acr_values` asked for. */
|
|
61
|
+
acr?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A personal access token the fake accepts with the `personal_access_token` grant.
|
|
65
|
+
*/
|
|
66
|
+
interface FakeAuthioPersonalAccessToken {
|
|
67
|
+
/** The `pat_…` value. */
|
|
68
|
+
token: string;
|
|
69
|
+
/** The credential's id, the token's `sub`. */
|
|
70
|
+
sub: string;
|
|
71
|
+
/** The consumer's client, for a consumer's token; the `authio` client of an account otherwise. */
|
|
72
|
+
clientId?: string;
|
|
73
|
+
/** Claims added to the access token. */
|
|
74
|
+
claims?: Record<string, unknown>;
|
|
31
75
|
}
|
|
32
76
|
/**
|
|
33
77
|
* An error the fake answers a request with.
|
|
@@ -45,9 +89,30 @@ interface FakeAuthioRecordedRequest {
|
|
|
45
89
|
path: string;
|
|
46
90
|
headers: Record<string, string>;
|
|
47
91
|
form: Record<string, string>;
|
|
92
|
+
/** The query parameters. */
|
|
93
|
+
query: Record<string, string>;
|
|
48
94
|
/** The client the request authenticated as, when it did. */
|
|
49
95
|
clientId?: string;
|
|
50
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* A back-channel logout token the fake posted to a client.
|
|
99
|
+
*/
|
|
100
|
+
interface FakeAuthioBackchannelDelivery {
|
|
101
|
+
clientId: string;
|
|
102
|
+
uri: string;
|
|
103
|
+
logoutToken: string;
|
|
104
|
+
/** The HTTP status the client answered, or 0 when it could not be reached. */
|
|
105
|
+
status: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The parameters an authorization ended with, as the fake sent them back.
|
|
109
|
+
*/
|
|
110
|
+
interface FakeAuthioAuthorizationOutcome {
|
|
111
|
+
/** `code`, `state` and `iss`, or `error`, `error_description`, `state` and `iss`. */
|
|
112
|
+
parameters: Record<string, string>;
|
|
113
|
+
/** The redirect URI with the parameters, for `response_mode=query`. */
|
|
114
|
+
callbackUrl: string | undefined;
|
|
115
|
+
}
|
|
51
116
|
/**
|
|
52
117
|
* What the device flow answers to successive polls.
|
|
53
118
|
*/
|
|
@@ -62,6 +127,7 @@ interface FakeAuthioOptions {
|
|
|
62
127
|
accessTokenLifetime?: number;
|
|
63
128
|
clients?: FakeAuthioClient[];
|
|
64
129
|
users?: FakeAuthioUser[];
|
|
130
|
+
personalAccessTokens?: FakeAuthioPersonalAccessToken[];
|
|
65
131
|
}
|
|
66
132
|
/**
|
|
67
133
|
* Options of a token minted directly.
|
|
@@ -82,34 +148,52 @@ interface FakeAuthioTokenOptions {
|
|
|
82
148
|
issuer?: string;
|
|
83
149
|
/** Signs with another key, so the signature does not verify. */
|
|
84
150
|
untrusted?: boolean;
|
|
151
|
+
/** Encrypts the token (nested JWT) to this public key, as Authio does for a client with an encryption key. */
|
|
152
|
+
encryptTo?: {
|
|
153
|
+
key: JWK;
|
|
154
|
+
algorithm?: "RSA-OAEP" | "RSA-OAEP-256";
|
|
155
|
+
encryptionMethod?: string;
|
|
156
|
+
};
|
|
85
157
|
}
|
|
158
|
+
type Endpoint = "token" | "introspect" | "revoke" | "userinfo" | "device" | "discovery" | "authorize" | "logout";
|
|
86
159
|
/**
|
|
87
|
-
* An in-memory Authio realm served over HTTP on loopback: discovery, JWKS,
|
|
88
|
-
*
|
|
89
|
-
* device
|
|
160
|
+
* An in-memory Authio realm served over HTTP on loopback: discovery, JWKS, authorization (PKCE, `state`, `nonce`,
|
|
161
|
+
* `prompt`, `max_age`, `acr_values`, `response_mode=web_message`, RFC 9207 `iss`), token (client credentials,
|
|
162
|
+
* authorization code with ID tokens, refresh, token exchange, password, device code, personal access token),
|
|
163
|
+
* introspection, revocation, UserInfo, device authorization, end session and back-channel logout delivery, with JWE
|
|
164
|
+
* (RSA-OAEP, RSA-OAEP-256) for clients that registered an encryption key.
|
|
90
165
|
*/
|
|
91
166
|
declare class FakeAuthio {
|
|
92
167
|
/** Every request received, in order. */
|
|
93
168
|
readonly requests: FakeAuthioRecordedRequest[];
|
|
94
169
|
/** Answers the next requests to an endpoint with these errors, in order, before answering normally. */
|
|
95
|
-
readonly failures: Map<
|
|
170
|
+
readonly failures: Map<Endpoint, FakeAuthioError[]>;
|
|
171
|
+
/** Every back-channel logout token posted, in order. */
|
|
172
|
+
readonly backchannelDeliveries: FakeAuthioBackchannelDelivery[];
|
|
96
173
|
/** What successive device-code polls answer; the last value repeats. Defaults to `["approved"]`. */
|
|
97
174
|
deviceOutcomes: FakeAuthioDeviceOutcome[];
|
|
98
175
|
/** Overrides the discovery document's issuer, to test the mismatch check. */
|
|
99
176
|
discoveryIssuer: string | undefined;
|
|
100
|
-
/** Answers UserInfo as `application/jwt`, signed by the realm key. */
|
|
177
|
+
/** Answers UserInfo as `application/jwt`, signed by the realm key (and encrypted for a client with a key). */
|
|
101
178
|
userInfoAsJwt: boolean;
|
|
179
|
+
/** Leaves `iss` out of authorization responses, to test the RFC 9207 check. */
|
|
180
|
+
omitAuthorizationIssuer: boolean;
|
|
102
181
|
/** Answers connected-account exchanges. Defaults to granting a token for the provider. */
|
|
103
182
|
connectionResponder: ((form: Record<string, string>) => FakeAuthioError | Record<string, unknown>) | undefined;
|
|
183
|
+
/** The person the authorization endpoint signs in when the request names none with `login_hint`. Defaults to the first user. */
|
|
184
|
+
signInAs: string | undefined;
|
|
104
185
|
private readonly clients;
|
|
105
186
|
private readonly users;
|
|
187
|
+
private readonly personalAccessTokens;
|
|
106
188
|
private readonly codes;
|
|
107
189
|
private readonly refreshTokens;
|
|
108
190
|
private readonly issued;
|
|
109
191
|
private readonly devicePolls;
|
|
110
192
|
private readonly lifetime;
|
|
193
|
+
private session;
|
|
111
194
|
private server;
|
|
112
195
|
private signingKey;
|
|
196
|
+
private verificationKey;
|
|
113
197
|
private untrustedKey;
|
|
114
198
|
private publicJwk;
|
|
115
199
|
private baseUrl;
|
|
@@ -128,10 +212,20 @@ declare class FakeAuthio {
|
|
|
128
212
|
get jwks(): {
|
|
129
213
|
keys: JWK[];
|
|
130
214
|
};
|
|
215
|
+
/** The session the authorization endpoint keeps (one browser), or `undefined` when nobody is signed in. */
|
|
216
|
+
get currentSession(): {
|
|
217
|
+
sub: string;
|
|
218
|
+
sid: string;
|
|
219
|
+
authTime: number;
|
|
220
|
+
} | undefined;
|
|
131
221
|
/** Registers a client. */
|
|
132
222
|
addClient(client: FakeAuthioClient): void;
|
|
133
223
|
/** Registers a person. */
|
|
134
224
|
addUser(user: FakeAuthioUser): void;
|
|
225
|
+
/** Registers a personal access token. */
|
|
226
|
+
addPersonalAccessToken(token: FakeAuthioPersonalAccessToken): void;
|
|
227
|
+
/** Ends the signed-in session without notifying anyone, as if it expired. */
|
|
228
|
+
endSession(): void;
|
|
135
229
|
/**
|
|
136
230
|
* Registers an authorization code for a person, as the authorization endpoint would after sign-in.
|
|
137
231
|
*/
|
|
@@ -142,13 +236,44 @@ declare class FakeAuthio {
|
|
|
142
236
|
scope?: string;
|
|
143
237
|
codeChallengeVerifier?: string;
|
|
144
238
|
resource?: string;
|
|
239
|
+
nonce?: string;
|
|
145
240
|
}): string;
|
|
241
|
+
/**
|
|
242
|
+
* Follows an authorization URL as a browser would, signing in `signInAs` (or the `login_hint`), and returns what
|
|
243
|
+
* Authio sent back: the callback URL for `response_mode=query`, the posted message's parameters for `web_message`.
|
|
244
|
+
*/
|
|
245
|
+
authorize(authorizationUrl: string): Promise<FakeAuthioAuthorizationOutcome>;
|
|
146
246
|
/**
|
|
147
247
|
* Mints an access token signed by the realm key, recorded so introspection and revocation know it.
|
|
148
248
|
*/
|
|
149
249
|
issueAccessToken(options?: FakeAuthioTokenOptions): Promise<string>;
|
|
150
|
-
/**
|
|
250
|
+
/**
|
|
251
|
+
* Mints a back-channel logout token for a client, signed by the realm key. `overrides` replaces claims (`undefined`
|
|
252
|
+
* removes one) and `type` the header `typ`, to build invalid ones in tests.
|
|
253
|
+
*/
|
|
254
|
+
createLogoutToken(options: {
|
|
255
|
+
clientId: string;
|
|
256
|
+
sub?: string;
|
|
257
|
+
sid?: string;
|
|
258
|
+
type?: string;
|
|
259
|
+
overrides?: Record<string, unknown>;
|
|
260
|
+
}): Promise<string>;
|
|
261
|
+
/**
|
|
262
|
+
* Posts a back-channel logout token to the client's `backchannelLogoutUri`, as Authio does when a session ends.
|
|
263
|
+
*
|
|
264
|
+
* @returns The HTTP status the client answered, or 0 when it could not be reached.
|
|
265
|
+
*/
|
|
266
|
+
deliverBackchannelLogout(clientId: string, options?: {
|
|
267
|
+
sub?: string;
|
|
268
|
+
sid?: string;
|
|
269
|
+
}): Promise<number>;
|
|
270
|
+
/** Marks a token revoked, as Authio would after a sign-out: an access token, or a refresh token, which is then forgotten. */
|
|
151
271
|
revokeToken(token: string): void;
|
|
272
|
+
/** Revokes every refresh token of a person, or of one Authio session (`sid`), as Authio does when a session ends. */
|
|
273
|
+
revokeRefreshTokens(options: {
|
|
274
|
+
sub?: string;
|
|
275
|
+
sid?: string;
|
|
276
|
+
}): void;
|
|
152
277
|
/** Forgets the recorded requests. */
|
|
153
278
|
clearRequests(): void;
|
|
154
279
|
/** The recorded requests to one endpoint path suffix, such as `/token`. */
|
|
@@ -158,6 +283,8 @@ declare class FakeAuthio {
|
|
|
158
283
|
private listen;
|
|
159
284
|
private handle;
|
|
160
285
|
private discovery;
|
|
286
|
+
private authorizeEndpoint;
|
|
287
|
+
private endSessionEndpoint;
|
|
161
288
|
private authenticate;
|
|
162
289
|
private token;
|
|
163
290
|
private tokenAnswer;
|
|
@@ -212,4 +339,4 @@ declare function createWebhookDelivery(type: string, data: unknown, secret: stri
|
|
|
212
339
|
sendEventIdHeader?: boolean;
|
|
213
340
|
}): Promise<FakeWebhookDelivery>;
|
|
214
341
|
|
|
215
|
-
export { FakeAuthio, type FakeAuthioClient, type FakeAuthioDeviceOutcome, type FakeAuthioError, type FakeAuthioOptions, type FakeAuthioRecordedRequest, type FakeAuthioTokenOptions, type FakeAuthioUser, type FakeWebhookDelivery, ManualClock, createWebhookDelivery };
|
|
342
|
+
export { FakeAuthio, type FakeAuthioAuthorizationOutcome, type FakeAuthioBackchannelDelivery, type FakeAuthioClient, type FakeAuthioClientEncryption, type FakeAuthioDeviceOutcome, type FakeAuthioError, type FakeAuthioOptions, type FakeAuthioPersonalAccessToken, type FakeAuthioRecordedRequest, type FakeAuthioTokenOptions, type FakeAuthioUser, type FakeWebhookDelivery, ManualClock, createWebhookDelivery };
|