@aooth/auth 0.1.7 → 0.1.8
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/atscript-db.cjs +36 -25
- package/dist/atscript-db.d.cts +28 -22
- package/dist/atscript-db.d.mts +28 -22
- package/dist/atscript-db.mjs +36 -25
- package/dist/authz.cjs +168 -0
- package/dist/authz.d.cts +252 -0
- package/dist/authz.d.mts +252 -0
- package/dist/authz.mjs +161 -0
- package/dist/client.cjs +59 -0
- package/dist/client.d.cts +64 -0
- package/dist/client.d.mts +64 -0
- package/dist/client.mjs +58 -0
- package/dist/clock-Bdsep_1j.mjs +4 -0
- package/dist/clock-BjXa0LXb.d.cts +14 -0
- package/dist/clock-BjXa0LXb.d.mts +14 -0
- package/dist/clock-Bl-H3eqE.cjs +9 -0
- package/dist/index.cjs +294 -65
- package/dist/index.d.cts +166 -44
- package/dist/index.d.mts +166 -44
- package/dist/index.mjs +289 -60
- package/dist/payload-BJjvj8AH.cjs +32 -0
- package/dist/payload-D-DzH5-J.mjs +27 -0
- package/dist/redis.cjs +9 -0
- package/dist/redis.d.cts +8 -7
- package/dist/redis.d.mts +8 -7
- package/dist/redis.mjs +9 -0
- package/dist/store-BG6m6oSJ.d.cts +263 -0
- package/dist/store-BG6m6oSJ.d.mts +263 -0
- package/package.json +28 -10
- package/src/atscript-db/auth-credential.as +16 -10
- package/src/atscript-db/auth-credential.as.d.ts +68 -0
- package/dist/store-B1t8KkfA.d.mts +0 -124
- package/dist/store-untAtWQz.d.cts +0 -124
|
@@ -24,26 +24,32 @@ export interface AoothAuthCredential {
|
|
|
24
24
|
kind?: string
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* Display metadata: ip, userAgent, fingerprint, label, plus the semantic
|
|
28
|
+
* credential kind (`cli-session` / `pat` / …) folded in by `issue()`. The
|
|
29
|
+
* `@db.json` column is schema-validated, so every field `CredentialMetadata`
|
|
30
|
+
* may carry must be declared here.
|
|
31
31
|
*/
|
|
32
32
|
@db.json
|
|
33
|
-
claims?: {
|
|
34
|
-
[/.*/]: string | number | boolean
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Display metadata: ip, userAgent, fingerprint, label. */
|
|
38
|
-
@db.json
|
|
39
33
|
metadata?: {
|
|
40
34
|
ip?: string
|
|
41
35
|
userAgent?: string
|
|
42
36
|
fingerprint?: string
|
|
43
37
|
label?: string
|
|
38
|
+
credentialKind?: string
|
|
44
39
|
}
|
|
45
40
|
|
|
46
41
|
/** Set by refresh-token rotation. */
|
|
47
42
|
parentCredentialId?: string
|
|
48
43
|
rotatedAt?: number.timestamp
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Stable session-family id. Minted once at login, copied forward on every
|
|
47
|
+
* rotation. Indexed so a store could group/revoke a family natively (the
|
|
48
|
+
* orchestrator groups in-memory today, but the index is cheap + forward-looking).
|
|
49
|
+
*/
|
|
50
|
+
@db.index.plain
|
|
51
|
+
sessionId?: string
|
|
52
|
+
|
|
53
|
+
/** Last-activity timestamp; written only under `trackLastSeen`. */
|
|
54
|
+
lastSeenAt?: number.timestamp
|
|
49
55
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// prettier-ignore-start
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* oxlint-disable */
|
|
4
|
+
/// <reference path="./auth-credential.as" />
|
|
5
|
+
/**
|
|
6
|
+
* 🪄 This file was generated by Atscript
|
|
7
|
+
* Do not edit this file!
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { TAtscriptTypeObject, TAtscriptTypeComplex, TAtscriptTypeFinal, TAtscriptTypeArray, TAtscriptAnnotatedType, TMetadataMap, Validator, TValidatorOptions } from "@atscript/typescript/utils"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Atscript interface **AoothAuthCredential**
|
|
14
|
+
* @see {@link ./auth-credential.as:3:18}
|
|
15
|
+
*/
|
|
16
|
+
export declare class AoothAuthCredential {
|
|
17
|
+
token: string
|
|
18
|
+
userId: string
|
|
19
|
+
issuedAt: number /* timestamp */
|
|
20
|
+
expiresAt: number /* timestamp */
|
|
21
|
+
kind?: string
|
|
22
|
+
metadata?: {
|
|
23
|
+
ip?: string
|
|
24
|
+
userAgent?: string
|
|
25
|
+
fingerprint?: string
|
|
26
|
+
label?: string
|
|
27
|
+
credentialKind?: string
|
|
28
|
+
}
|
|
29
|
+
parentCredentialId?: string
|
|
30
|
+
rotatedAt?: number /* timestamp */
|
|
31
|
+
sessionId?: string
|
|
32
|
+
lastSeenAt?: number /* timestamp */
|
|
33
|
+
static __is_atscript_annotated_type: true
|
|
34
|
+
static type: TAtscriptTypeObject<keyof AoothAuthCredential, AoothAuthCredential>
|
|
35
|
+
static metadata: TMetadataMap<AtscriptMetadata>
|
|
36
|
+
static validator: (opts?: Partial<TValidatorOptions>) => Validator<typeof AoothAuthCredential>
|
|
37
|
+
/** @deprecated JSON Schema support is disabled. Calling this method will throw a runtime error. To enable, set `jsonSchema: 'lazy'` or `jsonSchema: 'bundle'` in tsPlugin options, or add `@emit.jsonSchema` annotation to individual interfaces. */
|
|
38
|
+
static toJsonSchema: () => any
|
|
39
|
+
/** @deprecated Example Data support is disabled. To enable, set `exampleData: true` in tsPlugin options. */
|
|
40
|
+
static toExampleData?: () => any
|
|
41
|
+
static __flat: {
|
|
42
|
+
"token": string
|
|
43
|
+
"userId": string
|
|
44
|
+
"issuedAt": number /* timestamp */
|
|
45
|
+
"expiresAt": number /* timestamp */
|
|
46
|
+
"kind"?: string
|
|
47
|
+
"metadata"?: string
|
|
48
|
+
"parentCredentialId"?: string
|
|
49
|
+
"rotatedAt"?: number /* timestamp */
|
|
50
|
+
"sessionId"?: string
|
|
51
|
+
"lastSeenAt"?: number /* timestamp */
|
|
52
|
+
}
|
|
53
|
+
static __ownProps: {
|
|
54
|
+
"token": string
|
|
55
|
+
"userId": string
|
|
56
|
+
"issuedAt": number /* timestamp */
|
|
57
|
+
"expiresAt": number /* timestamp */
|
|
58
|
+
"kind"?: string
|
|
59
|
+
"metadata"?: string
|
|
60
|
+
"parentCredentialId"?: string
|
|
61
|
+
"rotatedAt"?: number /* timestamp */
|
|
62
|
+
"sessionId"?: string
|
|
63
|
+
"lastSeenAt"?: number /* timestamp */
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static __pk: string
|
|
67
|
+
}
|
|
68
|
+
// prettier-ignore-end
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
//#region src/credential/types.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* What a successful auth check produces.
|
|
4
|
-
* Generic over TClaims for typed custom claims.
|
|
5
|
-
*/
|
|
6
|
-
interface AuthContext<TClaims extends object = object> {
|
|
7
|
-
userId: string;
|
|
8
|
-
method: "session" | "token";
|
|
9
|
-
credentialId: string;
|
|
10
|
-
expiresAt: number;
|
|
11
|
-
claims?: TClaims;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Display metadata for stateful credentials.
|
|
15
|
-
* Extensible via TypeScript declaration merging:
|
|
16
|
-
* declare module '@aooth/auth' {
|
|
17
|
-
* interface CredentialMetadata { geoCountry?: string }
|
|
18
|
-
* }
|
|
19
|
-
*/
|
|
20
|
-
interface CredentialMetadata {
|
|
21
|
-
ip?: string;
|
|
22
|
-
userAgent?: string;
|
|
23
|
-
fingerprint?: string;
|
|
24
|
-
label?: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Persisted state of a credential.
|
|
28
|
-
*/
|
|
29
|
-
interface CredentialState<TClaims extends object = object> {
|
|
30
|
-
userId: string;
|
|
31
|
-
issuedAt: number;
|
|
32
|
-
expiresAt: number;
|
|
33
|
-
claims?: TClaims;
|
|
34
|
-
metadata?: CredentialMetadata;
|
|
35
|
-
/**
|
|
36
|
-
* Discriminant between access and refresh credentials persisted in the same store.
|
|
37
|
-
* Defaults to "access" when omitted.
|
|
38
|
-
*/
|
|
39
|
-
kind?: "access" | "refresh";
|
|
40
|
-
/** For rotated refresh tokens — id of the parent credential this one replaced */
|
|
41
|
-
parentCredentialId?: string;
|
|
42
|
-
/** Timestamp of rotation; used by sliding rotation grace period */
|
|
43
|
-
rotatedAt?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Result of issuing a credential or refreshing it.
|
|
47
|
-
*/
|
|
48
|
-
interface IssueResult {
|
|
49
|
-
accessToken: string;
|
|
50
|
-
refreshToken?: string;
|
|
51
|
-
accessExpiresAt: number;
|
|
52
|
-
refreshExpiresAt?: number;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Refresh token configuration.
|
|
56
|
-
*/
|
|
57
|
-
interface RefreshConfig {
|
|
58
|
-
/** Refresh token lifetime in milliseconds. */
|
|
59
|
-
ttl: number;
|
|
60
|
-
/**
|
|
61
|
-
* Rotation strategy. Defaults to 'sliding'.
|
|
62
|
-
*
|
|
63
|
-
* Note: 'sliding' grace-period replay tolerance only works against stateful
|
|
64
|
-
* stores (e.g. {@link CredentialStoreMemory}). Stateless stores (JWT,
|
|
65
|
-
* Encapsulated) cannot mutate an issued token in place; after the first
|
|
66
|
-
* rotation the old refresh becomes unusable, so 'sliding' degrades to
|
|
67
|
-
* 'always' semantics. Use 'always' explicitly for stateless deployments.
|
|
68
|
-
*/
|
|
69
|
-
rotation?: "none" | "always" | "sliding";
|
|
70
|
-
/** Grace period for sliding rotation, in milliseconds. Defaults to 30_000. */
|
|
71
|
-
rotationGraceMs?: number;
|
|
72
|
-
/** Theft detection hook — invoked when a previously-rotated refresh is reused. */
|
|
73
|
-
onRotationReuse?: (state: CredentialState) => void;
|
|
74
|
-
}
|
|
75
|
-
//#endregion
|
|
76
|
-
//#region src/stores/store.d.ts
|
|
77
|
-
/**
|
|
78
|
-
* Pluggable credential storage. Implementations: Memory, JWT, Encapsulated.
|
|
79
|
-
* Same shape works for stateful and stateless stores. Stateless stores treat
|
|
80
|
-
* the token as the state itself (sign/encrypt on persist, verify/decrypt on retrieve).
|
|
81
|
-
*
|
|
82
|
-
* `TClaims` is constrained to `extends object`, which TypeScript widens to
|
|
83
|
-
* include arrays, class instances, and `Function`. Pass a plain object type
|
|
84
|
-
* (e.g. `{ role: string; tenant: string }`); using arrays/classes will type-
|
|
85
|
-
* check but won't survive JSON-serialised stateless storage round-trips.
|
|
86
|
-
*/
|
|
87
|
-
interface CredentialStore<TClaims extends object = object> {
|
|
88
|
-
/** Persist state, return token. For stateless stores, token IS the state. */
|
|
89
|
-
persist(state: CredentialState<TClaims>, ttl?: number): Promise<string>;
|
|
90
|
-
/** Retrieve state from token. Returns null if expired/invalid/revoked. */
|
|
91
|
-
retrieve(token: string): Promise<CredentialState<TClaims> | null>;
|
|
92
|
-
/** Retrieve + invalidate (single-use). For stateless: needs denylist. */
|
|
93
|
-
consume(token: string): Promise<CredentialState<TClaims> | null>;
|
|
94
|
-
/**
|
|
95
|
-
* Update state. The returned token MAY differ from the input — stateful
|
|
96
|
-
* stores typically return the same token, while stateless stores re-issue
|
|
97
|
-
* a new token (denylisting the old). Callers must use the returned value.
|
|
98
|
-
*/
|
|
99
|
-
update(token: string, state: CredentialState<TClaims>): Promise<string>;
|
|
100
|
-
/** Revoke a single token. For stateless: requires denylist; otherwise throws. */
|
|
101
|
-
revoke(token: string): Promise<void>;
|
|
102
|
-
/**
|
|
103
|
-
* Revoke all credentials for a user. Returns count revoked.
|
|
104
|
-
* Stateless stores cannot enumerate individual tokens; they MAY implement
|
|
105
|
-
* the cascade via a per-user revocation epoch (see `CredentialStoreJwt`)
|
|
106
|
-
* and return a sentinel `1` to indicate "revocation took effect".
|
|
107
|
-
*/
|
|
108
|
-
revokeAllForUser(userId: string): Promise<number>;
|
|
109
|
-
/** List active credentials for a user (stateful only). */
|
|
110
|
-
listForUser?(userId: string): Promise<Array<CredentialState<TClaims> & {
|
|
111
|
-
token: string;
|
|
112
|
-
}>>;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Denylist for stateless revocation. Stores revoked-but-not-yet-expired token IDs.
|
|
116
|
-
* Auto-bounded by token TTLs.
|
|
117
|
-
*/
|
|
118
|
-
interface DenylistStore {
|
|
119
|
-
add(jti: string, expiresAt: number): Promise<void>;
|
|
120
|
-
has(jti: string): Promise<boolean>;
|
|
121
|
-
cleanup(): Promise<number>;
|
|
122
|
-
}
|
|
123
|
-
//#endregion
|
|
124
|
-
export { CredentialState as a, CredentialMetadata as i, DenylistStore as n, IssueResult as o, AuthContext as r, RefreshConfig as s, CredentialStore as t };
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
//#region src/credential/types.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* What a successful auth check produces.
|
|
4
|
-
* Generic over TClaims for typed custom claims.
|
|
5
|
-
*/
|
|
6
|
-
interface AuthContext<TClaims extends object = object> {
|
|
7
|
-
userId: string;
|
|
8
|
-
method: "session" | "token";
|
|
9
|
-
credentialId: string;
|
|
10
|
-
expiresAt: number;
|
|
11
|
-
claims?: TClaims;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Display metadata for stateful credentials.
|
|
15
|
-
* Extensible via TypeScript declaration merging:
|
|
16
|
-
* declare module '@aooth/auth' {
|
|
17
|
-
* interface CredentialMetadata { geoCountry?: string }
|
|
18
|
-
* }
|
|
19
|
-
*/
|
|
20
|
-
interface CredentialMetadata {
|
|
21
|
-
ip?: string;
|
|
22
|
-
userAgent?: string;
|
|
23
|
-
fingerprint?: string;
|
|
24
|
-
label?: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Persisted state of a credential.
|
|
28
|
-
*/
|
|
29
|
-
interface CredentialState<TClaims extends object = object> {
|
|
30
|
-
userId: string;
|
|
31
|
-
issuedAt: number;
|
|
32
|
-
expiresAt: number;
|
|
33
|
-
claims?: TClaims;
|
|
34
|
-
metadata?: CredentialMetadata;
|
|
35
|
-
/**
|
|
36
|
-
* Discriminant between access and refresh credentials persisted in the same store.
|
|
37
|
-
* Defaults to "access" when omitted.
|
|
38
|
-
*/
|
|
39
|
-
kind?: "access" | "refresh";
|
|
40
|
-
/** For rotated refresh tokens — id of the parent credential this one replaced */
|
|
41
|
-
parentCredentialId?: string;
|
|
42
|
-
/** Timestamp of rotation; used by sliding rotation grace period */
|
|
43
|
-
rotatedAt?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Result of issuing a credential or refreshing it.
|
|
47
|
-
*/
|
|
48
|
-
interface IssueResult {
|
|
49
|
-
accessToken: string;
|
|
50
|
-
refreshToken?: string;
|
|
51
|
-
accessExpiresAt: number;
|
|
52
|
-
refreshExpiresAt?: number;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Refresh token configuration.
|
|
56
|
-
*/
|
|
57
|
-
interface RefreshConfig {
|
|
58
|
-
/** Refresh token lifetime in milliseconds. */
|
|
59
|
-
ttl: number;
|
|
60
|
-
/**
|
|
61
|
-
* Rotation strategy. Defaults to 'sliding'.
|
|
62
|
-
*
|
|
63
|
-
* Note: 'sliding' grace-period replay tolerance only works against stateful
|
|
64
|
-
* stores (e.g. {@link CredentialStoreMemory}). Stateless stores (JWT,
|
|
65
|
-
* Encapsulated) cannot mutate an issued token in place; after the first
|
|
66
|
-
* rotation the old refresh becomes unusable, so 'sliding' degrades to
|
|
67
|
-
* 'always' semantics. Use 'always' explicitly for stateless deployments.
|
|
68
|
-
*/
|
|
69
|
-
rotation?: "none" | "always" | "sliding";
|
|
70
|
-
/** Grace period for sliding rotation, in milliseconds. Defaults to 30_000. */
|
|
71
|
-
rotationGraceMs?: number;
|
|
72
|
-
/** Theft detection hook — invoked when a previously-rotated refresh is reused. */
|
|
73
|
-
onRotationReuse?: (state: CredentialState) => void;
|
|
74
|
-
}
|
|
75
|
-
//#endregion
|
|
76
|
-
//#region src/stores/store.d.ts
|
|
77
|
-
/**
|
|
78
|
-
* Pluggable credential storage. Implementations: Memory, JWT, Encapsulated.
|
|
79
|
-
* Same shape works for stateful and stateless stores. Stateless stores treat
|
|
80
|
-
* the token as the state itself (sign/encrypt on persist, verify/decrypt on retrieve).
|
|
81
|
-
*
|
|
82
|
-
* `TClaims` is constrained to `extends object`, which TypeScript widens to
|
|
83
|
-
* include arrays, class instances, and `Function`. Pass a plain object type
|
|
84
|
-
* (e.g. `{ role: string; tenant: string }`); using arrays/classes will type-
|
|
85
|
-
* check but won't survive JSON-serialised stateless storage round-trips.
|
|
86
|
-
*/
|
|
87
|
-
interface CredentialStore<TClaims extends object = object> {
|
|
88
|
-
/** Persist state, return token. For stateless stores, token IS the state. */
|
|
89
|
-
persist(state: CredentialState<TClaims>, ttl?: number): Promise<string>;
|
|
90
|
-
/** Retrieve state from token. Returns null if expired/invalid/revoked. */
|
|
91
|
-
retrieve(token: string): Promise<CredentialState<TClaims> | null>;
|
|
92
|
-
/** Retrieve + invalidate (single-use). For stateless: needs denylist. */
|
|
93
|
-
consume(token: string): Promise<CredentialState<TClaims> | null>;
|
|
94
|
-
/**
|
|
95
|
-
* Update state. The returned token MAY differ from the input — stateful
|
|
96
|
-
* stores typically return the same token, while stateless stores re-issue
|
|
97
|
-
* a new token (denylisting the old). Callers must use the returned value.
|
|
98
|
-
*/
|
|
99
|
-
update(token: string, state: CredentialState<TClaims>): Promise<string>;
|
|
100
|
-
/** Revoke a single token. For stateless: requires denylist; otherwise throws. */
|
|
101
|
-
revoke(token: string): Promise<void>;
|
|
102
|
-
/**
|
|
103
|
-
* Revoke all credentials for a user. Returns count revoked.
|
|
104
|
-
* Stateless stores cannot enumerate individual tokens; they MAY implement
|
|
105
|
-
* the cascade via a per-user revocation epoch (see `CredentialStoreJwt`)
|
|
106
|
-
* and return a sentinel `1` to indicate "revocation took effect".
|
|
107
|
-
*/
|
|
108
|
-
revokeAllForUser(userId: string): Promise<number>;
|
|
109
|
-
/** List active credentials for a user (stateful only). */
|
|
110
|
-
listForUser?(userId: string): Promise<Array<CredentialState<TClaims> & {
|
|
111
|
-
token: string;
|
|
112
|
-
}>>;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Denylist for stateless revocation. Stores revoked-but-not-yet-expired token IDs.
|
|
116
|
-
* Auto-bounded by token TTLs.
|
|
117
|
-
*/
|
|
118
|
-
interface DenylistStore {
|
|
119
|
-
add(jti: string, expiresAt: number): Promise<void>;
|
|
120
|
-
has(jti: string): Promise<boolean>;
|
|
121
|
-
cleanup(): Promise<number>;
|
|
122
|
-
}
|
|
123
|
-
//#endregion
|
|
124
|
-
export { CredentialState as a, CredentialMetadata as i, DenylistStore as n, IssueResult as o, AuthContext as r, RefreshConfig as s, CredentialStore as t };
|