@aooth/auth 0.1.18 → 0.1.20
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 +106 -12
- package/dist/atscript-db.d.cts +85 -8
- package/dist/atscript-db.d.mts +85 -8
- package/dist/atscript-db.mjs +104 -11
- package/dist/authz.cjs +380 -16
- package/dist/authz.d.cts +337 -14
- package/dist/authz.d.mts +337 -14
- package/dist/authz.mjs +366 -12
- package/dist/{auth-code-store-B_m51OSB.cjs → dynamic-client-store-DAStgv2j.cjs} +74 -0
- package/dist/{auth-code-store-Dqc4rEOx.mjs → dynamic-client-store-DLRfntHr.mjs} +63 -1
- package/dist/{auth-code-store-BZ88d_tq.d.cts → dynamic-client-store-DzqdUwnw.d.cts} +112 -1
- package/dist/{auth-code-store-Om5MXNUT.d.mts → dynamic-client-store-oHEsQaJg.d.mts} +112 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.mts +4 -2
- package/package.json +19 -9
- package/src/atscript-db/auth-code.as +2 -0
- package/src/atscript-db/auth-code.as.d.ts +3 -0
- package/src/atscript-db/auth-credential.as +40 -14
- package/src/atscript-db/auth-credential.as.d.ts +23 -10
- package/src/atscript-db/dynamic-client.as +44 -0
- package/src/atscript-db/dynamic-client.as.d.ts +59 -0
- package/src/atscript-db/pending-authorization.as +7 -0
- package/src/atscript-db/pending-authorization.as.d.ts +6 -0
package/dist/atscript-db.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_clock = require("./clock-Bl-H3eqE.cjs");
|
|
3
3
|
const require_payload = require("./payload-BJjvj8AH.cjs");
|
|
4
|
-
const
|
|
4
|
+
const require_dynamic_client_store = require("./dynamic-client-store-DAStgv2j.cjs");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
//#region src/atscript-db/authz-stores.ts
|
|
7
7
|
/**
|
|
@@ -9,7 +9,7 @@ let node_crypto = require("node:crypto");
|
|
|
9
9
|
* fresh opaque `handle`; `get` rejects (and lazily evicts) a past-expiry row;
|
|
10
10
|
* `delete` drops it once consumed. PK is `handle`, so reads/deletes are O(1).
|
|
11
11
|
*/
|
|
12
|
-
var PendingAuthorizationStoreAtscriptDb = class extends
|
|
12
|
+
var PendingAuthorizationStoreAtscriptDb = class extends require_dynamic_client_store.PendingAuthorizationStore {
|
|
13
13
|
table;
|
|
14
14
|
clock;
|
|
15
15
|
ttlMs;
|
|
@@ -32,7 +32,9 @@ var PendingAuthorizationStoreAtscriptDb = class extends require_auth_code_store.
|
|
|
32
32
|
createdAt: now,
|
|
33
33
|
expiresAt,
|
|
34
34
|
...rec.clientId !== void 0 && { clientId: rec.clientId },
|
|
35
|
+
...rec.clientName !== void 0 && { clientName: rec.clientName },
|
|
35
36
|
...rec.clientState !== void 0 && { clientState: rec.clientState },
|
|
37
|
+
...rec.resource !== void 0 && { resource: rec.resource },
|
|
36
38
|
...rec.scope !== void 0 && { scope: rec.scope },
|
|
37
39
|
...rec.nonce !== void 0 && { nonce: rec.nonce },
|
|
38
40
|
...rec.idToken !== void 0 && { idToken: rec.idToken },
|
|
@@ -69,7 +71,9 @@ function rowToPending(row) {
|
|
|
69
71
|
expiresAt: row.expiresAt
|
|
70
72
|
};
|
|
71
73
|
if (row.clientId != null) out.clientId = row.clientId;
|
|
74
|
+
if (row.clientName != null) out.clientName = row.clientName;
|
|
72
75
|
if (row.clientState != null) out.clientState = row.clientState;
|
|
76
|
+
if (row.resource != null) out.resource = row.resource;
|
|
73
77
|
if (row.scope != null) out.scope = row.scope;
|
|
74
78
|
if (row.nonce != null) out.nonce = row.nonce;
|
|
75
79
|
if (row.idToken != null) out.idToken = row.idToken;
|
|
@@ -86,7 +90,7 @@ function rowToPending(row) {
|
|
|
86
90
|
* back-button replay loses the race and gets `null`. (The delete is the claim,
|
|
87
91
|
* so no version column is needed — `deleteOne(PK)` is atomic per the DB engine.)
|
|
88
92
|
*/
|
|
89
|
-
var AuthCodeStoreAtscriptDb = class extends
|
|
93
|
+
var AuthCodeStoreAtscriptDb = class extends require_dynamic_client_store.AuthCodeStore {
|
|
90
94
|
table;
|
|
91
95
|
clock;
|
|
92
96
|
ttlMs;
|
|
@@ -107,6 +111,7 @@ var AuthCodeStoreAtscriptDb = class extends require_auth_code_store.AuthCodeStor
|
|
|
107
111
|
expiresAt: this.clock.now() + this.ttlMs,
|
|
108
112
|
...rec.clientId !== void 0 && { clientId: rec.clientId },
|
|
109
113
|
...rec.scope !== void 0 && { scope: rec.scope },
|
|
114
|
+
...rec.resource !== void 0 && { resource: rec.resource },
|
|
110
115
|
...rec.nonce !== void 0 && { nonce: rec.nonce },
|
|
111
116
|
...rec.idToken !== void 0 && { idToken: rec.idToken },
|
|
112
117
|
...rec.accessToken !== void 0 && { accessToken: rec.accessToken },
|
|
@@ -134,12 +139,83 @@ function rowToAuthCode(row) {
|
|
|
134
139
|
};
|
|
135
140
|
if (row.clientId != null) out.clientId = row.clientId;
|
|
136
141
|
if (row.scope != null) out.scope = row.scope;
|
|
142
|
+
if (row.resource != null) out.resource = row.resource;
|
|
137
143
|
if (row.nonce != null) out.nonce = row.nonce;
|
|
138
144
|
if (row.idToken != null) out.idToken = row.idToken;
|
|
139
145
|
if (row.accessToken != null) out.accessToken = row.accessToken;
|
|
140
146
|
if (row.audience != null) out.audience = row.audience;
|
|
141
147
|
return out;
|
|
142
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Durable {@link DynamicClientStore}. Long-lived rows (a connector caches its
|
|
151
|
+
* `client_id` across grants). `touch` is the portable findOne + replaceOne
|
|
152
|
+
* (same trick as `CredentialStoreAtscriptDb.touch` — no engine-specific patch
|
|
153
|
+
* op); `deleteUnusedBefore` is one mass `deleteMany` over
|
|
154
|
+
* `createdAt < cutoff && lastUsedAt unset` — the never-used GC.
|
|
155
|
+
*/
|
|
156
|
+
var DynamicClientStoreAtscriptDb = class extends require_dynamic_client_store.DynamicClientStore {
|
|
157
|
+
table;
|
|
158
|
+
clock;
|
|
159
|
+
constructor(opts) {
|
|
160
|
+
super();
|
|
161
|
+
this.table = opts.table;
|
|
162
|
+
this.clock = opts.clock ?? require_clock.defaultClock;
|
|
163
|
+
}
|
|
164
|
+
async create(rec) {
|
|
165
|
+
const row = {
|
|
166
|
+
clientId: (0, node_crypto.randomUUID)(),
|
|
167
|
+
redirectUris: JSON.stringify(rec.redirectUris),
|
|
168
|
+
tokenEndpointAuthMethod: rec.tokenEndpointAuthMethod,
|
|
169
|
+
grantTypes: JSON.stringify(rec.grantTypes),
|
|
170
|
+
responseTypes: JSON.stringify(rec.responseTypes),
|
|
171
|
+
createdAt: this.clock.now(),
|
|
172
|
+
...rec.clientName !== void 0 && { clientName: rec.clientName },
|
|
173
|
+
...rec.scope !== void 0 && { scope: rec.scope }
|
|
174
|
+
};
|
|
175
|
+
await this.table.insertOne(row);
|
|
176
|
+
return rowToDynamicClient(row);
|
|
177
|
+
}
|
|
178
|
+
async get(clientId) {
|
|
179
|
+
const row = await this.table.findOne({ filter: { clientId } });
|
|
180
|
+
return row ? rowToDynamicClient(row) : null;
|
|
181
|
+
}
|
|
182
|
+
async delete(clientId) {
|
|
183
|
+
const { deletedCount } = await this.table.deleteOne(clientId);
|
|
184
|
+
return deletedCount > 0;
|
|
185
|
+
}
|
|
186
|
+
async count() {
|
|
187
|
+
return this.table.count({});
|
|
188
|
+
}
|
|
189
|
+
async touch(clientId, at) {
|
|
190
|
+
const row = await this.table.findOne({ filter: { clientId } });
|
|
191
|
+
if (!row) return;
|
|
192
|
+
await this.table.replaceOne({
|
|
193
|
+
...row,
|
|
194
|
+
lastUsedAt: at
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async deleteUnusedBefore(cutoff) {
|
|
198
|
+
const { deletedCount } = await this.table.deleteMany({
|
|
199
|
+
createdAt: { $lt: cutoff },
|
|
200
|
+
lastUsedAt: { $exists: false }
|
|
201
|
+
});
|
|
202
|
+
return deletedCount;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
function rowToDynamicClient(row) {
|
|
206
|
+
const out = {
|
|
207
|
+
clientId: row.clientId,
|
|
208
|
+
redirectUris: JSON.parse(row.redirectUris),
|
|
209
|
+
tokenEndpointAuthMethod: row.tokenEndpointAuthMethod,
|
|
210
|
+
grantTypes: JSON.parse(row.grantTypes),
|
|
211
|
+
responseTypes: JSON.parse(row.responseTypes),
|
|
212
|
+
createdAt: row.createdAt
|
|
213
|
+
};
|
|
214
|
+
if (row.clientName != null) out.clientName = row.clientName;
|
|
215
|
+
if (row.scope != null) out.scope = row.scope;
|
|
216
|
+
if (row.lastUsedAt != null) out.lastUsedAt = row.lastUsedAt;
|
|
217
|
+
return out;
|
|
218
|
+
}
|
|
143
219
|
//#endregion
|
|
144
220
|
//#region src/atscript-db/index.ts
|
|
145
221
|
/**
|
|
@@ -157,13 +233,15 @@ function rowToAuthCode(row) {
|
|
|
157
233
|
*/
|
|
158
234
|
var CredentialStoreAtscriptDb = class {
|
|
159
235
|
table;
|
|
236
|
+
metadataField;
|
|
160
237
|
constructor(opts) {
|
|
161
238
|
this.table = opts.table;
|
|
239
|
+
this.metadataField = opts.metadataField;
|
|
162
240
|
}
|
|
163
241
|
async persist(state, ttl) {
|
|
164
242
|
const token = (0, node_crypto.randomUUID)();
|
|
165
243
|
const expiresAt = typeof ttl === "number" ? Date.now() + ttl : state.expiresAt;
|
|
166
|
-
await this.table.insertOne(stateToRow(state, token, expiresAt));
|
|
244
|
+
await this.table.insertOne(stateToRow(state, token, expiresAt, this.metadataField));
|
|
167
245
|
return token;
|
|
168
246
|
}
|
|
169
247
|
async retrieve(token) {
|
|
@@ -173,7 +251,7 @@ var CredentialStoreAtscriptDb = class {
|
|
|
173
251
|
await this.table.deleteOne(token).catch(() => {});
|
|
174
252
|
return null;
|
|
175
253
|
}
|
|
176
|
-
return rowToState(row);
|
|
254
|
+
return rowToState(row, this.metadataField);
|
|
177
255
|
}
|
|
178
256
|
async consume(token) {
|
|
179
257
|
const state = await this.retrieve(token);
|
|
@@ -187,7 +265,7 @@ var CredentialStoreAtscriptDb = class {
|
|
|
187
265
|
await this.revoke(token);
|
|
188
266
|
return token;
|
|
189
267
|
}
|
|
190
|
-
await this.table.replaceOne(stateToRow(state, token, state.expiresAt));
|
|
268
|
+
await this.table.replaceOne(stateToRow(state, token, state.expiresAt, this.metadataField));
|
|
191
269
|
return token;
|
|
192
270
|
}
|
|
193
271
|
async revoke(token) {
|
|
@@ -216,7 +294,7 @@ var CredentialStoreAtscriptDb = class {
|
|
|
216
294
|
continue;
|
|
217
295
|
}
|
|
218
296
|
out.push({
|
|
219
|
-
...rowToState(row),
|
|
297
|
+
...rowToState(row, this.metadataField),
|
|
220
298
|
token: row.token
|
|
221
299
|
});
|
|
222
300
|
}
|
|
@@ -229,30 +307,45 @@ var CredentialStoreAtscriptDb = class {
|
|
|
229
307
|
* (so an envelope field wins a name clash), then the fixed envelope fields and
|
|
230
308
|
* the resolved `token` + `expiresAt`. Shared by `persist` and `update`, which
|
|
231
309
|
* differ only in the `expiresAt` they resolve.
|
|
310
|
+
*
|
|
311
|
+
* The envelope's `metadata` is written to the consumer's `metadataField`
|
|
312
|
+
* column (a dynamic key the static row type can't carry) — only when the
|
|
313
|
+
* field is configured; otherwise metadata is silently not persisted.
|
|
232
314
|
*/
|
|
233
|
-
function stateToRow(state, token, expiresAt) {
|
|
234
|
-
|
|
315
|
+
function stateToRow(state, token, expiresAt, metadataField) {
|
|
316
|
+
const row = {
|
|
235
317
|
...require_payload.credentialPayloadOf(state),
|
|
236
318
|
token,
|
|
237
319
|
userId: state.userId,
|
|
238
320
|
issuedAt: state.issuedAt,
|
|
239
321
|
expiresAt,
|
|
240
322
|
kind: state.kind,
|
|
241
|
-
metadata: state.metadata,
|
|
242
323
|
parentCredentialId: state.parentCredentialId,
|
|
243
324
|
rotatedAt: state.rotatedAt,
|
|
244
325
|
sessionId: state.sessionId,
|
|
245
326
|
lastSeenAt: state.lastSeenAt
|
|
246
327
|
};
|
|
328
|
+
if (metadataField !== void 0 && state.metadata !== void 0) row[metadataField] = state.metadata;
|
|
329
|
+
return row;
|
|
247
330
|
}
|
|
248
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Inverse of {@link stateToRow}. The consumer's `metadataField` column maps
|
|
333
|
+
* back onto the envelope's `metadata` — and is excluded from the extracted
|
|
334
|
+
* payload (it is envelope data riding under a consumer-chosen name, not a
|
|
335
|
+
* typed payload field).
|
|
336
|
+
*/
|
|
337
|
+
function rowToState(row, metadataField) {
|
|
249
338
|
const state = {
|
|
250
339
|
...require_payload.credentialPayloadOf(row),
|
|
251
340
|
userId: row.userId,
|
|
252
341
|
issuedAt: row.issuedAt,
|
|
253
342
|
expiresAt: row.expiresAt
|
|
254
343
|
};
|
|
255
|
-
if (
|
|
344
|
+
if (metadataField !== void 0) {
|
|
345
|
+
delete state[metadataField];
|
|
346
|
+
const metadata = row[metadataField];
|
|
347
|
+
if (metadata !== void 0) state.metadata = metadata;
|
|
348
|
+
}
|
|
256
349
|
if (row.kind === "access" || row.kind === "refresh") state.kind = row.kind;
|
|
257
350
|
if (row.parentCredentialId !== void 0) state.parentCredentialId = row.parentCredentialId;
|
|
258
351
|
if (row.rotatedAt !== void 0) state.rotatedAt = row.rotatedAt;
|
|
@@ -263,4 +356,5 @@ function rowToState(row) {
|
|
|
263
356
|
//#endregion
|
|
264
357
|
exports.AuthCodeStoreAtscriptDb = AuthCodeStoreAtscriptDb;
|
|
265
358
|
exports.CredentialStoreAtscriptDb = CredentialStoreAtscriptDb;
|
|
359
|
+
exports.DynamicClientStoreAtscriptDb = DynamicClientStoreAtscriptDb;
|
|
266
360
|
exports.PendingAuthorizationStoreAtscriptDb = PendingAuthorizationStoreAtscriptDb;
|
package/dist/atscript-db.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as CredentialState, t as CredentialStore } from "./store-BG6m6oSJ.cjs";
|
|
2
2
|
import { t as Clock } from "./clock-BjXa0LXb.cjs";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as NewDynamicClient, f as NewPendingAuthorization, m as PendingAuthorizationStore, n as DynamicClientStore, o as AuthCode, p as PendingAuthorization, s as AuthCodeStore, t as DynamicClient, u as NewAuthCode } from "./dynamic-client-store-DzqdUwnw.cjs";
|
|
4
4
|
|
|
5
5
|
//#region src/atscript-db/authz-stores.d.ts
|
|
6
6
|
/**
|
|
@@ -22,7 +22,9 @@ interface PendingAuthorizationRow {
|
|
|
22
22
|
redirectUri: string;
|
|
23
23
|
codeChallenge: string;
|
|
24
24
|
clientId?: string;
|
|
25
|
+
clientName?: string;
|
|
25
26
|
clientState?: string;
|
|
27
|
+
resource?: string;
|
|
26
28
|
scope?: string;
|
|
27
29
|
nonce?: string;
|
|
28
30
|
idToken?: boolean;
|
|
@@ -84,6 +86,7 @@ interface AuthCodeRow {
|
|
|
84
86
|
redirectUri: string;
|
|
85
87
|
clientId?: string;
|
|
86
88
|
scope?: string;
|
|
89
|
+
resource?: string;
|
|
87
90
|
nonce?: string;
|
|
88
91
|
idToken?: boolean;
|
|
89
92
|
accessToken?: boolean;
|
|
@@ -130,6 +133,71 @@ declare class AuthCodeStoreAtscriptDb extends AuthCodeStore {
|
|
|
130
133
|
}>;
|
|
131
134
|
consume(code: string): Promise<AuthCode | null>;
|
|
132
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Persisted row — mirrors `AoothDynamicClient` (`dynamic-client.as`). The
|
|
138
|
+
* three array fields are JSON-STRING columns (same opaque-string pattern as
|
|
139
|
+
* `tokenPolicy` above): a `string[]` column would need engine-specific array
|
|
140
|
+
* support, and all matching happens in `DynamicClientPolicy` after parse.
|
|
141
|
+
*/
|
|
142
|
+
interface DynamicClientRow {
|
|
143
|
+
clientId: string;
|
|
144
|
+
clientName?: string;
|
|
145
|
+
/** `JSON.stringify(string[])`. */
|
|
146
|
+
redirectUris: string;
|
|
147
|
+
tokenEndpointAuthMethod: string;
|
|
148
|
+
/** `JSON.stringify(string[])`. */
|
|
149
|
+
grantTypes: string;
|
|
150
|
+
/** `JSON.stringify(string[])`. */
|
|
151
|
+
responseTypes: string;
|
|
152
|
+
scope?: string;
|
|
153
|
+
createdAt: number;
|
|
154
|
+
lastUsedAt?: number;
|
|
155
|
+
}
|
|
156
|
+
/** Structural surface of `AtscriptDbTable` for the dynamic-client adapter. */
|
|
157
|
+
interface DynamicClientTable {
|
|
158
|
+
insertOne(row: DynamicClientRow): Promise<{
|
|
159
|
+
insertedId: unknown;
|
|
160
|
+
}>;
|
|
161
|
+
findOne(query: {
|
|
162
|
+
filter: Record<string, unknown>;
|
|
163
|
+
}): Promise<DynamicClientRow | null>;
|
|
164
|
+
count(query: {
|
|
165
|
+
filter?: Record<string, unknown>;
|
|
166
|
+
}): Promise<number>;
|
|
167
|
+
replaceOne(row: DynamicClientRow): Promise<{
|
|
168
|
+
matchedCount: number;
|
|
169
|
+
modifiedCount: number;
|
|
170
|
+
}>;
|
|
171
|
+
deleteOne(idOrPk: unknown): Promise<{
|
|
172
|
+
deletedCount: number;
|
|
173
|
+
}>;
|
|
174
|
+
deleteMany(filter: Record<string, unknown>): Promise<{
|
|
175
|
+
deletedCount: number;
|
|
176
|
+
}>;
|
|
177
|
+
}
|
|
178
|
+
interface DynamicClientStoreAtscriptDbOptions {
|
|
179
|
+
table: DynamicClientTable;
|
|
180
|
+
/** Injectable clock for deterministic `createdAt`. Defaults to {@link defaultClock}. */
|
|
181
|
+
clock?: Clock;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Durable {@link DynamicClientStore}. Long-lived rows (a connector caches its
|
|
185
|
+
* `client_id` across grants). `touch` is the portable findOne + replaceOne
|
|
186
|
+
* (same trick as `CredentialStoreAtscriptDb.touch` — no engine-specific patch
|
|
187
|
+
* op); `deleteUnusedBefore` is one mass `deleteMany` over
|
|
188
|
+
* `createdAt < cutoff && lastUsedAt unset` — the never-used GC.
|
|
189
|
+
*/
|
|
190
|
+
declare class DynamicClientStoreAtscriptDb extends DynamicClientStore {
|
|
191
|
+
private readonly table;
|
|
192
|
+
private readonly clock;
|
|
193
|
+
constructor(opts: DynamicClientStoreAtscriptDbOptions);
|
|
194
|
+
create(rec: NewDynamicClient): Promise<DynamicClient>;
|
|
195
|
+
get(clientId: string): Promise<DynamicClient | null>;
|
|
196
|
+
delete(clientId: string): Promise<boolean>;
|
|
197
|
+
count(): Promise<number>;
|
|
198
|
+
touch(clientId: string, at: number): Promise<void>;
|
|
199
|
+
deleteUnusedBefore(cutoff: number): Promise<number>;
|
|
200
|
+
}
|
|
133
201
|
//#endregion
|
|
134
202
|
//#region src/atscript-db/index.d.ts
|
|
135
203
|
/**
|
|
@@ -142,6 +210,11 @@ declare class AuthCodeStoreAtscriptDb extends AuthCodeStore {
|
|
|
142
210
|
* The consumer's typed payload `TPayload` (the root fields they add to their
|
|
143
211
|
* `extends AoothAuthCredential` model) is intersected flat — those become real
|
|
144
212
|
* typed columns, replacing the dropped free-form `claims` blob.
|
|
213
|
+
*
|
|
214
|
+
* There is NO `metadata` envelope column: credential metadata is
|
|
215
|
+
* consumer-declared (a fully-typed `@db.json` field on the extending model,
|
|
216
|
+
* marked `@aooth.auth.metadata`) and mapped dynamically through the
|
|
217
|
+
* `metadataField` option below.
|
|
145
218
|
*/
|
|
146
219
|
type AuthCredentialRow<TPayload extends object = object> = {
|
|
147
220
|
token: string;
|
|
@@ -149,12 +222,6 @@ type AuthCredentialRow<TPayload extends object = object> = {
|
|
|
149
222
|
issuedAt: number;
|
|
150
223
|
expiresAt: number;
|
|
151
224
|
kind?: string;
|
|
152
|
-
metadata?: {
|
|
153
|
-
ip?: string;
|
|
154
|
-
userAgent?: string;
|
|
155
|
-
fingerprint?: string;
|
|
156
|
-
label?: string;
|
|
157
|
-
};
|
|
158
225
|
parentCredentialId?: string;
|
|
159
226
|
rotatedAt?: number;
|
|
160
227
|
sessionId?: string;
|
|
@@ -190,6 +257,15 @@ interface AuthCredentialTable<TPayload extends object = object> {
|
|
|
190
257
|
}
|
|
191
258
|
interface CredentialStoreAtscriptDbOptions<TPayload extends object> {
|
|
192
259
|
table: AuthCredentialTable<TPayload>;
|
|
260
|
+
/**
|
|
261
|
+
* Name of the consumer's `@aooth.auth.metadata`-annotated column — the
|
|
262
|
+
* fully-typed `@db.json` field declared on their `extends AoothAuthCredential`
|
|
263
|
+
* model that persists the envelope's `metadata`. Resolved at boot by
|
|
264
|
+
* `getAoothCredentialMetadataSpec` (`@aooth/arbac-moost/atscript`) and
|
|
265
|
+
* threaded here as plain config — same pattern as `UserStore.handleFields`.
|
|
266
|
+
* Absent → metadata is not persisted/read by this store.
|
|
267
|
+
*/
|
|
268
|
+
metadataField?: string;
|
|
193
269
|
}
|
|
194
270
|
/**
|
|
195
271
|
* atscript-db-backed `CredentialStore`.
|
|
@@ -206,6 +282,7 @@ interface CredentialStoreAtscriptDbOptions<TPayload extends object> {
|
|
|
206
282
|
*/
|
|
207
283
|
declare class CredentialStoreAtscriptDb<TPayload extends object = object> implements CredentialStore<TPayload> {
|
|
208
284
|
private readonly table;
|
|
285
|
+
private readonly metadataField;
|
|
209
286
|
constructor(opts: CredentialStoreAtscriptDbOptions<TPayload>);
|
|
210
287
|
persist(state: CredentialState & TPayload, ttl?: number): Promise<string>;
|
|
211
288
|
retrieve(token: string): Promise<(CredentialState & TPayload) | null>;
|
|
@@ -219,4 +296,4 @@ declare class CredentialStoreAtscriptDb<TPayload extends object = object> implem
|
|
|
219
296
|
}>>;
|
|
220
297
|
}
|
|
221
298
|
//#endregion
|
|
222
|
-
export { AuthCodeRow, AuthCodeStoreAtscriptDb, AuthCodeStoreAtscriptDbOptions, AuthCodeTable, AuthCredentialRow, AuthCredentialTable, CredentialStoreAtscriptDb, PendingAuthorizationRow, PendingAuthorizationStoreAtscriptDb, PendingAuthorizationStoreAtscriptDbOptions, PendingAuthorizationTable };
|
|
299
|
+
export { AuthCodeRow, AuthCodeStoreAtscriptDb, AuthCodeStoreAtscriptDbOptions, AuthCodeTable, AuthCredentialRow, AuthCredentialTable, CredentialStoreAtscriptDb, DynamicClientRow, DynamicClientStoreAtscriptDb, DynamicClientStoreAtscriptDbOptions, DynamicClientTable, PendingAuthorizationRow, PendingAuthorizationStoreAtscriptDb, PendingAuthorizationStoreAtscriptDbOptions, PendingAuthorizationTable };
|
package/dist/atscript-db.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as CredentialState, t as CredentialStore } from "./store-BG6m6oSJ.mjs";
|
|
2
2
|
import { t as Clock } from "./clock-BjXa0LXb.mjs";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as NewDynamicClient, f as NewPendingAuthorization, m as PendingAuthorizationStore, n as DynamicClientStore, o as AuthCode, p as PendingAuthorization, s as AuthCodeStore, t as DynamicClient, u as NewAuthCode } from "./dynamic-client-store-oHEsQaJg.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/atscript-db/authz-stores.d.ts
|
|
6
6
|
/**
|
|
@@ -22,7 +22,9 @@ interface PendingAuthorizationRow {
|
|
|
22
22
|
redirectUri: string;
|
|
23
23
|
codeChallenge: string;
|
|
24
24
|
clientId?: string;
|
|
25
|
+
clientName?: string;
|
|
25
26
|
clientState?: string;
|
|
27
|
+
resource?: string;
|
|
26
28
|
scope?: string;
|
|
27
29
|
nonce?: string;
|
|
28
30
|
idToken?: boolean;
|
|
@@ -84,6 +86,7 @@ interface AuthCodeRow {
|
|
|
84
86
|
redirectUri: string;
|
|
85
87
|
clientId?: string;
|
|
86
88
|
scope?: string;
|
|
89
|
+
resource?: string;
|
|
87
90
|
nonce?: string;
|
|
88
91
|
idToken?: boolean;
|
|
89
92
|
accessToken?: boolean;
|
|
@@ -130,6 +133,71 @@ declare class AuthCodeStoreAtscriptDb extends AuthCodeStore {
|
|
|
130
133
|
}>;
|
|
131
134
|
consume(code: string): Promise<AuthCode | null>;
|
|
132
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Persisted row — mirrors `AoothDynamicClient` (`dynamic-client.as`). The
|
|
138
|
+
* three array fields are JSON-STRING columns (same opaque-string pattern as
|
|
139
|
+
* `tokenPolicy` above): a `string[]` column would need engine-specific array
|
|
140
|
+
* support, and all matching happens in `DynamicClientPolicy` after parse.
|
|
141
|
+
*/
|
|
142
|
+
interface DynamicClientRow {
|
|
143
|
+
clientId: string;
|
|
144
|
+
clientName?: string;
|
|
145
|
+
/** `JSON.stringify(string[])`. */
|
|
146
|
+
redirectUris: string;
|
|
147
|
+
tokenEndpointAuthMethod: string;
|
|
148
|
+
/** `JSON.stringify(string[])`. */
|
|
149
|
+
grantTypes: string;
|
|
150
|
+
/** `JSON.stringify(string[])`. */
|
|
151
|
+
responseTypes: string;
|
|
152
|
+
scope?: string;
|
|
153
|
+
createdAt: number;
|
|
154
|
+
lastUsedAt?: number;
|
|
155
|
+
}
|
|
156
|
+
/** Structural surface of `AtscriptDbTable` for the dynamic-client adapter. */
|
|
157
|
+
interface DynamicClientTable {
|
|
158
|
+
insertOne(row: DynamicClientRow): Promise<{
|
|
159
|
+
insertedId: unknown;
|
|
160
|
+
}>;
|
|
161
|
+
findOne(query: {
|
|
162
|
+
filter: Record<string, unknown>;
|
|
163
|
+
}): Promise<DynamicClientRow | null>;
|
|
164
|
+
count(query: {
|
|
165
|
+
filter?: Record<string, unknown>;
|
|
166
|
+
}): Promise<number>;
|
|
167
|
+
replaceOne(row: DynamicClientRow): Promise<{
|
|
168
|
+
matchedCount: number;
|
|
169
|
+
modifiedCount: number;
|
|
170
|
+
}>;
|
|
171
|
+
deleteOne(idOrPk: unknown): Promise<{
|
|
172
|
+
deletedCount: number;
|
|
173
|
+
}>;
|
|
174
|
+
deleteMany(filter: Record<string, unknown>): Promise<{
|
|
175
|
+
deletedCount: number;
|
|
176
|
+
}>;
|
|
177
|
+
}
|
|
178
|
+
interface DynamicClientStoreAtscriptDbOptions {
|
|
179
|
+
table: DynamicClientTable;
|
|
180
|
+
/** Injectable clock for deterministic `createdAt`. Defaults to {@link defaultClock}. */
|
|
181
|
+
clock?: Clock;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Durable {@link DynamicClientStore}. Long-lived rows (a connector caches its
|
|
185
|
+
* `client_id` across grants). `touch` is the portable findOne + replaceOne
|
|
186
|
+
* (same trick as `CredentialStoreAtscriptDb.touch` — no engine-specific patch
|
|
187
|
+
* op); `deleteUnusedBefore` is one mass `deleteMany` over
|
|
188
|
+
* `createdAt < cutoff && lastUsedAt unset` — the never-used GC.
|
|
189
|
+
*/
|
|
190
|
+
declare class DynamicClientStoreAtscriptDb extends DynamicClientStore {
|
|
191
|
+
private readonly table;
|
|
192
|
+
private readonly clock;
|
|
193
|
+
constructor(opts: DynamicClientStoreAtscriptDbOptions);
|
|
194
|
+
create(rec: NewDynamicClient): Promise<DynamicClient>;
|
|
195
|
+
get(clientId: string): Promise<DynamicClient | null>;
|
|
196
|
+
delete(clientId: string): Promise<boolean>;
|
|
197
|
+
count(): Promise<number>;
|
|
198
|
+
touch(clientId: string, at: number): Promise<void>;
|
|
199
|
+
deleteUnusedBefore(cutoff: number): Promise<number>;
|
|
200
|
+
}
|
|
133
201
|
//#endregion
|
|
134
202
|
//#region src/atscript-db/index.d.ts
|
|
135
203
|
/**
|
|
@@ -142,6 +210,11 @@ declare class AuthCodeStoreAtscriptDb extends AuthCodeStore {
|
|
|
142
210
|
* The consumer's typed payload `TPayload` (the root fields they add to their
|
|
143
211
|
* `extends AoothAuthCredential` model) is intersected flat — those become real
|
|
144
212
|
* typed columns, replacing the dropped free-form `claims` blob.
|
|
213
|
+
*
|
|
214
|
+
* There is NO `metadata` envelope column: credential metadata is
|
|
215
|
+
* consumer-declared (a fully-typed `@db.json` field on the extending model,
|
|
216
|
+
* marked `@aooth.auth.metadata`) and mapped dynamically through the
|
|
217
|
+
* `metadataField` option below.
|
|
145
218
|
*/
|
|
146
219
|
type AuthCredentialRow<TPayload extends object = object> = {
|
|
147
220
|
token: string;
|
|
@@ -149,12 +222,6 @@ type AuthCredentialRow<TPayload extends object = object> = {
|
|
|
149
222
|
issuedAt: number;
|
|
150
223
|
expiresAt: number;
|
|
151
224
|
kind?: string;
|
|
152
|
-
metadata?: {
|
|
153
|
-
ip?: string;
|
|
154
|
-
userAgent?: string;
|
|
155
|
-
fingerprint?: string;
|
|
156
|
-
label?: string;
|
|
157
|
-
};
|
|
158
225
|
parentCredentialId?: string;
|
|
159
226
|
rotatedAt?: number;
|
|
160
227
|
sessionId?: string;
|
|
@@ -190,6 +257,15 @@ interface AuthCredentialTable<TPayload extends object = object> {
|
|
|
190
257
|
}
|
|
191
258
|
interface CredentialStoreAtscriptDbOptions<TPayload extends object> {
|
|
192
259
|
table: AuthCredentialTable<TPayload>;
|
|
260
|
+
/**
|
|
261
|
+
* Name of the consumer's `@aooth.auth.metadata`-annotated column — the
|
|
262
|
+
* fully-typed `@db.json` field declared on their `extends AoothAuthCredential`
|
|
263
|
+
* model that persists the envelope's `metadata`. Resolved at boot by
|
|
264
|
+
* `getAoothCredentialMetadataSpec` (`@aooth/arbac-moost/atscript`) and
|
|
265
|
+
* threaded here as plain config — same pattern as `UserStore.handleFields`.
|
|
266
|
+
* Absent → metadata is not persisted/read by this store.
|
|
267
|
+
*/
|
|
268
|
+
metadataField?: string;
|
|
193
269
|
}
|
|
194
270
|
/**
|
|
195
271
|
* atscript-db-backed `CredentialStore`.
|
|
@@ -206,6 +282,7 @@ interface CredentialStoreAtscriptDbOptions<TPayload extends object> {
|
|
|
206
282
|
*/
|
|
207
283
|
declare class CredentialStoreAtscriptDb<TPayload extends object = object> implements CredentialStore<TPayload> {
|
|
208
284
|
private readonly table;
|
|
285
|
+
private readonly metadataField;
|
|
209
286
|
constructor(opts: CredentialStoreAtscriptDbOptions<TPayload>);
|
|
210
287
|
persist(state: CredentialState & TPayload, ttl?: number): Promise<string>;
|
|
211
288
|
retrieve(token: string): Promise<(CredentialState & TPayload) | null>;
|
|
@@ -219,4 +296,4 @@ declare class CredentialStoreAtscriptDb<TPayload extends object = object> implem
|
|
|
219
296
|
}>>;
|
|
220
297
|
}
|
|
221
298
|
//#endregion
|
|
222
|
-
export { AuthCodeRow, AuthCodeStoreAtscriptDb, AuthCodeStoreAtscriptDbOptions, AuthCodeTable, AuthCredentialRow, AuthCredentialTable, CredentialStoreAtscriptDb, PendingAuthorizationRow, PendingAuthorizationStoreAtscriptDb, PendingAuthorizationStoreAtscriptDbOptions, PendingAuthorizationTable };
|
|
299
|
+
export { AuthCodeRow, AuthCodeStoreAtscriptDb, AuthCodeStoreAtscriptDbOptions, AuthCodeTable, AuthCredentialRow, AuthCredentialTable, CredentialStoreAtscriptDb, DynamicClientRow, DynamicClientStoreAtscriptDb, DynamicClientStoreAtscriptDbOptions, DynamicClientTable, PendingAuthorizationRow, PendingAuthorizationStoreAtscriptDb, PendingAuthorizationStoreAtscriptDbOptions, PendingAuthorizationTable };
|