@udibo/oauth2 0.4.1 → 0.5.1
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 +3 -3
- package/SECURITY.md +0 -4
- package/esm/adapters/hono/_common.d.ts +10 -13
- package/esm/adapters/hono/_common.js +11 -20
- package/esm/adapters/hono/authorization-server.d.ts +16 -10
- package/esm/adapters/hono/authorization-server.js +13 -8
- package/esm/adapters/hono/bff/auth-request-store.d.ts +4 -0
- package/esm/adapters/hono/bff/auth-request-store.js +4 -0
- package/esm/adapters/hono/bff/bff.d.ts +29 -18
- package/esm/adapters/hono/bff/bff.js +15 -11
- package/esm/adapters/hono/bff/proxy.js +7 -55
- package/esm/adapters/hono/bff/session-store.d.ts +9 -9
- package/esm/adapters/hono/bff/session-store.js +3 -2
- package/esm/adapters/hono/bff/testing.d.ts +14 -3
- package/esm/adapters/hono/bff/testing.js +14 -3
- package/esm/adapters/hono/identity.d.ts +5 -3
- package/esm/adapters/hono/identity.js +1 -17
- package/esm/adapters/hono/resource-server.d.ts +3 -2
- package/esm/adapters/hono/resource-server.js +3 -2
- package/esm/client/_http.d.ts +4 -7
- package/esm/client/_http.js +4 -37
- package/esm/client/base.d.ts +3 -6
- package/esm/client/bff-client.d.ts +7 -6
- package/esm/client/bff-client.js +7 -6
- package/esm/client/browser-storage.d.ts +33 -34
- package/esm/client/browser-storage.js +47 -32
- package/esm/client/check.d.ts +10 -3
- package/esm/client/check.js +28 -8
- package/esm/client/direct-client.d.ts +49 -29
- package/esm/client/direct-client.js +59 -59
- package/esm/client/discovery-cache.d.ts +12 -5
- package/esm/client/discovery-cache.js +11 -4
- package/esm/client/events.d.ts +11 -3
- package/esm/client/events.js +1 -1
- package/esm/client/mod.d.ts +6 -4
- package/esm/client/mod.js +5 -3
- package/esm/client/storage.d.ts +53 -23
- package/esm/client/storage.js +43 -15
- package/esm/errors.d.ts +15 -12
- package/esm/errors.js +12 -8
- package/esm/identity/delivery.d.ts +7 -7
- package/esm/identity/delivery.js +1 -2
- package/esm/identity/errors.d.ts +10 -4
- package/esm/identity/errors.js +4 -1
- package/esm/identity/events.d.ts +21 -5
- package/esm/identity/events.js +4 -2
- package/esm/identity/external/_shared.d.ts +5 -7
- package/esm/identity/external/_shared.js +5 -7
- package/esm/identity/external/_token-exchange.d.ts +3 -6
- package/esm/identity/external/_token-exchange.js +2 -5
- package/esm/identity/external/apple-client-secret.d.ts +13 -8
- package/esm/identity/external/apple-client-secret.js +9 -6
- package/esm/identity/external/apple.d.ts +17 -10
- package/esm/identity/external/apple.js +12 -9
- package/esm/identity/external/discord.d.ts +5 -1
- package/esm/identity/external/errors.d.ts +6 -2
- package/esm/identity/external/errors.js +6 -2
- package/esm/identity/external/flow.d.ts +9 -6
- package/esm/identity/external/flow.js +6 -5
- package/esm/identity/external/github.d.ts +7 -3
- package/esm/identity/external/github.js +2 -2
- package/esm/identity/external/google.d.ts +5 -1
- package/esm/identity/external/oauth2.d.ts +13 -2
- package/esm/identity/external/oauth2.js +3 -3
- package/esm/identity/external/oidc.d.ts +21 -10
- package/esm/identity/external/oidc.js +11 -6
- package/esm/identity/external/provider.d.ts +4 -2
- package/esm/identity/identifier.d.ts +6 -5
- package/esm/identity/identifier.js +6 -5
- package/esm/identity/lockout.d.ts +4 -3
- package/esm/identity/lockout.js +4 -3
- package/esm/identity/mfa/mod.d.ts +2 -1
- package/esm/identity/mfa/mod.js +2 -1
- package/esm/identity/mfa/recovery-codes.d.ts +2 -1
- package/esm/identity/mfa/service.d.ts +29 -11
- package/esm/identity/mfa/service.js +35 -11
- package/esm/identity/mfa/totp.d.ts +4 -2
- package/esm/identity/mfa/totp.js +4 -2
- package/esm/identity/migration.d.ts +8 -7
- package/esm/identity/migration.js +9 -12
- package/esm/identity/mod.d.ts +2 -2
- package/esm/identity/mod.js +2 -2
- package/esm/identity/otp.d.ts +23 -16
- package/esm/identity/otp.js +13 -12
- package/esm/identity/password-policy.d.ts +3 -3
- package/esm/identity/password-policy.js +3 -3
- package/esm/identity/password.d.ts +23 -20
- package/esm/identity/password.js +15 -16
- package/esm/identity/rate-limit.d.ts +1 -7
- package/esm/identity/rate-limit.js +1 -2
- package/esm/identity/service.d.ts +76 -44
- package/esm/identity/service.js +86 -60
- package/esm/identity/session.d.ts +5 -4
- package/esm/identity/session.js +5 -4
- package/esm/identity/token-flow.d.ts +8 -8
- package/esm/identity/token-flow.js +5 -6
- package/esm/models/client.d.ts +7 -4
- package/esm/models/token.d.ts +2 -3
- package/esm/react/callback.d.ts +3 -3
- package/esm/react/callback.js +3 -3
- package/esm/react/components/class-names.d.ts +3 -6
- package/esm/react/components/class-names.js +3 -6
- package/esm/react/components/internal.d.ts +7 -17
- package/esm/react/components/internal.js +7 -17
- package/esm/react/components/mod.d.ts +7 -5
- package/esm/react/components/mod.js +7 -5
- package/esm/react/components/types.d.ts +8 -6
- package/esm/react/context.d.ts +3 -3
- package/esm/react/provider.d.ts +3 -2
- package/esm/react/provider.js +0 -13
- package/esm/react/require-auth.d.ts +0 -3
- package/esm/react/require-auth.js +0 -3
- package/esm/react/testing.d.ts +3 -2
- package/esm/react/testing.js +3 -3
- package/esm/react/use-oauth2.d.ts +1 -1
- package/esm/server/authorization-server.d.ts +81 -54
- package/esm/server/authorization-server.js +76 -100
- package/esm/server/grants/authorization-code.d.ts +7 -3
- package/esm/server/grants/authorization-code.js +6 -2
- package/esm/server/grants/device-authorization.d.ts +1 -1
- package/esm/server/grants/grant.d.ts +15 -8
- package/esm/server/grants/grant.js +26 -18
- package/esm/server/grants/password.d.ts +1 -1
- package/esm/server/grants/refresh-token.d.ts +6 -3
- package/esm/server/grants/refresh-token.js +4 -3
- package/esm/server/introspection-token-reader.d.ts +16 -7
- package/esm/server/introspection-token-reader.js +9 -3
- package/esm/server/jwks-token-reader.d.ts +3 -3
- package/esm/server/jwks-token-reader.js +3 -3
- package/esm/server/redirect-uri.d.ts +6 -9
- package/esm/server/redirect-uri.js +7 -34
- package/esm/server/resource-server.d.ts +5 -3
- package/esm/server/resource-server.js +5 -3
- package/esm/server/services/client.d.ts +5 -1
- package/esm/server/services/device-authorization.d.ts +6 -6
- package/esm/server/services/token.d.ts +15 -8
- package/esm/server/services/token.js +1 -1
- package/esm/server/signing-keys.d.ts +24 -9
- package/esm/server/signing-keys.js +20 -9
- package/esm/testing/contract/mod.d.ts +3 -3
- package/esm/testing/contract/mod.js +3 -3
- package/esm/testing/contract/tenant.d.ts +1 -1
- package/esm/testing/contract/tenant.js +2 -2
- package/esm/testing/mod.d.ts +6 -4
- package/esm/testing/mod.js +6 -4
- package/esm/testing/services.d.ts +1 -1
- package/esm/testing/services.js +1 -1
- package/esm/testing/tenant.d.ts +14 -5
- package/esm/utils/_buffer.d.ts +3 -2
- package/esm/utils/_buffer.js +3 -2
- package/esm/utils/_timing-safe.d.ts +8 -6
- package/esm/utils/_timing-safe.js +8 -6
- package/esm/utils/basic-auth.d.ts +5 -12
- package/esm/utils/basic-auth.js +5 -12
- package/esm/utils/crypto.d.ts +2 -1
- package/esm/utils/crypto.js +2 -1
- package/esm/utils/text.d.ts +2 -9
- package/esm/utils/text.js +2 -9
- package/esm/utils/url.d.ts +2 -2
- package/esm/utils/url.js +0 -2
- package/package.json +1 -1
package/esm/testing/tenant.d.ts
CHANGED
|
@@ -102,7 +102,7 @@ export interface FakeTenantOptions {
|
|
|
102
102
|
issuer: string;
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
* A stand-in for a Udibo tenant, for testing an app that signs in against one
|
|
105
|
+
* A stand-in for a Udibo Identity tenant, for testing an app that signs in against one
|
|
106
106
|
* without running the identity service. It answers the tenant's protocol
|
|
107
107
|
* surface — discovery, authorize, token, introspection, UserInfo, JWKS — the
|
|
108
108
|
* caller's own `GET /api/memberships`, and the two authorization questions,
|
|
@@ -124,9 +124,17 @@ export interface FakeTenant {
|
|
|
124
124
|
addUser(user: FakeTenantUser): Promise<void>;
|
|
125
125
|
/** Adds an organization. Throws on a duplicate id. */
|
|
126
126
|
addOrganization(organization: FakeTenantOrganization): void;
|
|
127
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* Makes a person a member of an organization, replacing any earlier
|
|
129
|
+
* membership. Throws when the organization does not exist.
|
|
130
|
+
*/
|
|
128
131
|
addMember(organizationId: string, userId: string, membership?: FakeTenantMembership): void;
|
|
129
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* Ends a membership. From then on introspection and `/api/check` stop
|
|
134
|
+
* answering for that organization on credentials issued in it, and UserInfo
|
|
135
|
+
* drops its `org_*` claims; a JWT access token or id_token already minted
|
|
136
|
+
* keeps its claims until it expires.
|
|
137
|
+
*/
|
|
130
138
|
removeMember(organizationId: string, userId: string): void;
|
|
131
139
|
/** Registers a resource type, so `/api/check` accepts it. */
|
|
132
140
|
registerResourceType(type: string): void;
|
|
@@ -134,12 +142,13 @@ export interface FakeTenant {
|
|
|
134
142
|
grant(grant: FakeTenantGrant): void;
|
|
135
143
|
/**
|
|
136
144
|
* Chooses who the next authorization requests authenticate as, until
|
|
137
|
-
* called again. With nobody chosen, authorize answers `
|
|
145
|
+
* called again. With nobody chosen, authorize answers `access_denied`.
|
|
138
146
|
*/
|
|
139
147
|
signInAs(userId: string | null, signIn?: FakeTenantSignIn): void;
|
|
140
148
|
/**
|
|
141
149
|
* Mints an access token without the browser flow, for testing an API
|
|
142
|
-
* directly. JWT or opaque as the client is registered.
|
|
150
|
+
* directly. JWT or opaque as the client is registered. Throws when the
|
|
151
|
+
* client or user does not exist.
|
|
143
152
|
*/
|
|
144
153
|
issueAccessToken(request: FakeTenantTokenRequest): Promise<string>;
|
|
145
154
|
}
|
package/esm/utils/_buffer.d.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Copies the viewed bytes into a standalone `ArrayBuffer`, for passing a
|
|
8
|
+
* `Uint8Array<ArrayBufferLike>` where Web Crypto's `BufferSource` type does not
|
|
9
|
+
* accept it.
|
|
9
10
|
*/
|
|
10
11
|
export declare function toArrayBuffer(bytes: Uint8Array): ArrayBuffer;
|
package/esm/utils/_buffer.js
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Copies the viewed bytes into a standalone `ArrayBuffer`, for passing a
|
|
8
|
+
* `Uint8Array<ArrayBufferLike>` where Web Crypto's `BufferSource` type does not
|
|
9
|
+
* accept it.
|
|
9
10
|
*/
|
|
10
11
|
export function toArrayBuffer(bytes) {
|
|
11
12
|
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Internal
|
|
2
|
+
* Internal timing-safe matching for secret candidates.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* Compares `target` against every candidate with no early exit, so the scan's
|
|
8
|
+
* duration does not reveal where a match occurred. Each comparison is
|
|
9
|
+
* {@link timingSafeEqualString}, which returns early on a byte-length mismatch,
|
|
10
|
+
* so candidates of a different length than `target` are distinguishable by
|
|
11
|
+
* timing. Returns the index of the *last* matching candidate, or `undefined`
|
|
12
|
+
* when none match — order candidates least- to most-preferred so a duplicate
|
|
13
|
+
* resolves to the preferred entry.
|
|
12
14
|
*/
|
|
13
15
|
export declare function timingSafeMatchIndex(candidates: string[], target: string): number | undefined;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Internal
|
|
2
|
+
* Internal timing-safe matching for secret candidates.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { timingSafeEqualString } from "./crypto.js";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* Compares `target` against every candidate with no early exit, so the scan's
|
|
9
|
+
* duration does not reveal where a match occurred. Each comparison is
|
|
10
|
+
* {@link timingSafeEqualString}, which returns early on a byte-length mismatch,
|
|
11
|
+
* so candidates of a different length than `target` are distinguishable by
|
|
12
|
+
* timing. Returns the index of the *last* matching candidate, or `undefined`
|
|
13
|
+
* when none match — order candidates least- to most-preferred so a duplicate
|
|
14
|
+
* resolves to the preferred entry.
|
|
13
15
|
*/
|
|
14
16
|
export function timingSafeMatchIndex(candidates, target) {
|
|
15
17
|
let index;
|
|
@@ -18,9 +18,8 @@ export interface BasicAuth {
|
|
|
18
18
|
* trip. A segment that is not valid percent-encoding is taken verbatim, so a
|
|
19
19
|
* client that sends such characters un-encoded still authenticates.
|
|
20
20
|
*
|
|
21
|
-
* @
|
|
22
|
-
*
|
|
23
|
-
* @throws {InvalidClientError} If the header is missing or malformed
|
|
21
|
+
* @throws {InvalidClientError} If the header is missing, not `Basic`, not
|
|
22
|
+
* valid base64, or does not decode to `name:pass` with a non-empty name.
|
|
24
23
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
|
|
25
24
|
*/
|
|
26
25
|
export declare function parseBasicAuth(authorization: string | null): BasicAuth;
|
|
@@ -33,18 +32,12 @@ export declare function parseBasicAuth(authorization: string | null): BasicAuth;
|
|
|
33
32
|
* only of `A-Z`, `a-z`, `0-9`, `-`, `_`, `.` and `*` encode byte-identically to
|
|
34
33
|
* their raw form; every other character, `~` included, is percent-encoded.
|
|
35
34
|
*
|
|
36
|
-
* @
|
|
37
|
-
* @param clientSecret The client secret
|
|
38
|
-
* @returns The encoded Authorization header value
|
|
35
|
+
* @returns The `Basic …` Authorization header value.
|
|
39
36
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
|
|
40
37
|
*/
|
|
41
38
|
export declare function encodeBasicAuth(clientId: string, clientSecret: string): string;
|
|
42
39
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* segments the same way {@link parseBasicAuth} does.
|
|
46
|
-
*
|
|
47
|
-
* @param authorization The Authorization header value
|
|
48
|
-
* @returns The parsed credentials or undefined
|
|
40
|
+
* Non-throwing {@link parseBasicAuth}: returns `undefined` wherever that would
|
|
41
|
+
* throw — a missing, non-`Basic`, badly encoded or malformed header.
|
|
49
42
|
*/
|
|
50
43
|
export declare function tryParseBasicAuth(authorization: string | null): BasicAuth | undefined;
|
package/esm/utils/basic-auth.js
CHANGED
|
@@ -30,9 +30,8 @@ function formUrlDecode(value) {
|
|
|
30
30
|
* trip. A segment that is not valid percent-encoding is taken verbatim, so a
|
|
31
31
|
* client that sends such characters un-encoded still authenticates.
|
|
32
32
|
*
|
|
33
|
-
* @
|
|
34
|
-
*
|
|
35
|
-
* @throws {InvalidClientError} If the header is missing or malformed
|
|
33
|
+
* @throws {InvalidClientError} If the header is missing, not `Basic`, not
|
|
34
|
+
* valid base64, or does not decode to `name:pass` with a non-empty name.
|
|
36
35
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
|
|
37
36
|
*/
|
|
38
37
|
export function parseBasicAuth(authorization) {
|
|
@@ -68,21 +67,15 @@ export function parseBasicAuth(authorization) {
|
|
|
68
67
|
* only of `A-Z`, `a-z`, `0-9`, `-`, `_`, `.` and `*` encode byte-identically to
|
|
69
68
|
* their raw form; every other character, `~` included, is percent-encoded.
|
|
70
69
|
*
|
|
71
|
-
* @
|
|
72
|
-
* @param clientSecret The client secret
|
|
73
|
-
* @returns The encoded Authorization header value
|
|
70
|
+
* @returns The `Basic …` Authorization header value.
|
|
74
71
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
|
|
75
72
|
*/
|
|
76
73
|
export function encodeBasicAuth(clientId, clientSecret) {
|
|
77
74
|
return `Basic ${btoa(`${formUrlEncode(clientId)}:${formUrlEncode(clientSecret)}`)}`;
|
|
78
75
|
}
|
|
79
76
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* segments the same way {@link parseBasicAuth} does.
|
|
83
|
-
*
|
|
84
|
-
* @param authorization The Authorization header value
|
|
85
|
-
* @returns The parsed credentials or undefined
|
|
77
|
+
* Non-throwing {@link parseBasicAuth}: returns `undefined` wherever that would
|
|
78
|
+
* throw — a missing, non-`Basic`, badly encoded or malformed header.
|
|
86
79
|
*/
|
|
87
80
|
export function tryParseBasicAuth(authorization) {
|
|
88
81
|
if (!authorization)
|
package/esm/utils/crypto.d.ts
CHANGED
|
@@ -70,7 +70,8 @@ export declare function randomToken(bytes?: number): string;
|
|
|
70
70
|
* secret is persisted (e.g. as a lookup key) — use {@link deriveSealKey} so the
|
|
71
71
|
* sealing key is independent of that stored hash.
|
|
72
72
|
*
|
|
73
|
-
* @throws if the secret
|
|
73
|
+
* @throws {Error} if the secret is shorter than 16 bytes. Length is all that is
|
|
74
|
+
* checked; supply 32+ bytes of real entropy.
|
|
74
75
|
*/
|
|
75
76
|
export declare function deriveAesKey(secret: string | Uint8Array): Promise<CryptoKey>;
|
|
76
77
|
/**
|
package/esm/utils/crypto.js
CHANGED
|
@@ -88,7 +88,8 @@ export function randomToken(bytes = 32) {
|
|
|
88
88
|
* secret is persisted (e.g. as a lookup key) — use {@link deriveSealKey} so the
|
|
89
89
|
* sealing key is independent of that stored hash.
|
|
90
90
|
*
|
|
91
|
-
* @throws if the secret
|
|
91
|
+
* @throws {Error} if the secret is shorter than 16 bytes. Length is all that is
|
|
92
|
+
* checked; supply 32+ bytes of real entropy.
|
|
92
93
|
*/
|
|
93
94
|
export async function deriveAesKey(secret) {
|
|
94
95
|
const raw = toBytes(secret);
|
package/esm/utils/text.d.ts
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bounding and flattening for text a remote server chose.
|
|
3
3
|
*
|
|
4
|
-
* Lives in `utils/` rather than beside either caller because both ladders that
|
|
5
|
-
* turn a server's bytes into an error message — the client's `_http.ts` and
|
|
6
|
-
* the connectors' `_token-exchange.ts` — must sanitize identically, and the
|
|
7
|
-
* client cannot reach up into `identity/external/`.
|
|
8
|
-
*
|
|
9
4
|
* @module
|
|
10
5
|
*/
|
|
11
6
|
/** Characters of remote-supplied text kept in an error message. */
|
|
12
7
|
export declare const PROVIDER_TEXT_MAX_LENGTH = 200;
|
|
13
8
|
/**
|
|
14
9
|
* Bounds and flattens a remote-supplied string for inclusion in an error
|
|
15
|
-
* message.
|
|
10
|
+
* message. Each run of C0/C1 control characters becomes one space (and the
|
|
11
|
+
* result is trimmed) so a hostile `error_description`
|
|
16
12
|
* cannot forge a log line or inject an ANSI escape in a consumer's console,
|
|
17
13
|
* the result is capped at {@link PROVIDER_TEXT_MAX_LENGTH}, and a surrogate
|
|
18
14
|
* pair split by that cap is repaired rather than left lone. Use this on
|
|
19
15
|
* every byte a remote server chose that reaches a message.
|
|
20
|
-
*
|
|
21
|
-
* @param value The remote-supplied text.
|
|
22
|
-
* @returns The flattened, capped, well-formed text.
|
|
23
16
|
*/
|
|
24
17
|
export declare function sanitizeProviderText(value: string): string;
|
package/esm/utils/text.js
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bounding and flattening for text a remote server chose.
|
|
3
3
|
*
|
|
4
|
-
* Lives in `utils/` rather than beside either caller because both ladders that
|
|
5
|
-
* turn a server's bytes into an error message — the client's `_http.ts` and
|
|
6
|
-
* the connectors' `_token-exchange.ts` — must sanitize identically, and the
|
|
7
|
-
* client cannot reach up into `identity/external/`.
|
|
8
|
-
*
|
|
9
4
|
* @module
|
|
10
5
|
*/
|
|
11
6
|
/** Characters of remote-supplied text kept in an error message. */
|
|
12
7
|
export const PROVIDER_TEXT_MAX_LENGTH = 200;
|
|
13
8
|
/**
|
|
14
9
|
* Bounds and flattens a remote-supplied string for inclusion in an error
|
|
15
|
-
* message.
|
|
10
|
+
* message. Each run of C0/C1 control characters becomes one space (and the
|
|
11
|
+
* result is trimmed) so a hostile `error_description`
|
|
16
12
|
* cannot forge a log line or inject an ANSI escape in a consumer's console,
|
|
17
13
|
* the result is capped at {@link PROVIDER_TEXT_MAX_LENGTH}, and a surrogate
|
|
18
14
|
* pair split by that cap is repaired rather than left lone. Use this on
|
|
19
15
|
* every byte a remote server chose that reaches a message.
|
|
20
|
-
*
|
|
21
|
-
* @param value The remote-supplied text.
|
|
22
|
-
* @returns The flattened, capped, well-formed text.
|
|
23
16
|
*/
|
|
24
17
|
export function sanitizeProviderText(value) {
|
|
25
18
|
// deno-lint-ignore no-control-regex
|
package/esm/utils/url.d.ts
CHANGED
|
@@ -38,8 +38,8 @@ export declare function safeReturnTo(value: string | null | undefined, fallback?
|
|
|
38
38
|
export interface LoginContinuationOptions {
|
|
39
39
|
/**
|
|
40
40
|
* The authorization endpoint (absolute URL or path). When `returnTo` points at
|
|
41
|
-
* it, the flow is **resumed** (the in-flight authorize request already
|
|
42
|
-
*
|
|
41
|
+
* it, the flow is **resumed** (the in-flight authorize request already carries
|
|
42
|
+
* its `state`). Omit it and every `returnTo` starts a fresh login.
|
|
43
43
|
*/
|
|
44
44
|
authorizeEndpoint?: string;
|
|
45
45
|
/** The login path to start a fresh login. Defaults to `"/auth/login"`. */
|
package/esm/utils/url.js
CHANGED
|
@@ -79,8 +79,6 @@ export function safeReturnTo(value, fallback = "/") {
|
|
|
79
79
|
export function loginContinuation(returnTo, options = {}) {
|
|
80
80
|
const safe = safeReturnTo(returnTo, options.defaultReturnTo ?? "/");
|
|
81
81
|
if (options.authorizeEndpoint) {
|
|
82
|
-
// Compare path only so the in-flight authorize query (client_id, state, …)
|
|
83
|
-
// is preserved; the base lets absolute and relative inputs both resolve.
|
|
84
82
|
const base = "http://login.continuation.local";
|
|
85
83
|
const authorizePath = new URL(options.authorizeEndpoint, base).pathname;
|
|
86
84
|
if (new URL(safe, base).pathname === authorizePath)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@udibo/oauth2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A flexible OAuth2 toolkit: framework-agnostic authorization & resource servers, a typed client, Hono adapters (including a backend-for-frontend), and React bindings.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|