@kubun/store-credential 0.13.0 → 0.14.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/lib/api.d.ts +10 -0
- package/lib/api.js +19 -0
- package/lib/index.d.ts +1 -1
- package/lib/migrations.js +8 -0
- package/lib/tables.d.ts +19 -0
- package/package.json +7 -7
package/lib/api.d.ts
CHANGED
|
@@ -155,5 +155,15 @@ export type CredentialStoreAPI = {
|
|
|
155
155
|
* that is now revoked.
|
|
156
156
|
*/
|
|
157
157
|
listHeldSubjects(): Promise<Array<HeldCredentialSubject>>;
|
|
158
|
+
/**
|
|
159
|
+
* The entry id currently pointed to by an opaque `(namespace, key)`, or
|
|
160
|
+
* `null` when unset. Neither argument is interpreted — a caller normalizes
|
|
161
|
+
* whatever it means by "key" before calling.
|
|
162
|
+
*/
|
|
163
|
+
getAliasEntryID(namespace: string, key: string): Promise<string | null>;
|
|
164
|
+
/** Point `(namespace, key)` at `entryID`, replacing any prior target. */
|
|
165
|
+
setAliasEntryID(namespace: string, key: string, entryID: string): Promise<void>;
|
|
166
|
+
/** Clear an alias. A no-op, not an error, when none is set. */
|
|
167
|
+
deleteAliasEntryID(namespace: string, key: string): Promise<void>;
|
|
158
168
|
};
|
|
159
169
|
export declare function createCredentialStore(db: Kysely<CredentialTables>, adapter: Adapter): CredentialStoreAPI;
|
package/lib/api.js
CHANGED
|
@@ -409,6 +409,25 @@ export function createCredentialStore(db, adapter) {
|
|
|
409
409
|
subjectID: row.subject_id,
|
|
410
410
|
opHash: row.op_hash
|
|
411
411
|
}));
|
|
412
|
+
},
|
|
413
|
+
async getAliasEntryID (namespace, key) {
|
|
414
|
+
const row = await db.selectFrom('kubun_credential_aliases').select('entry_id').where('namespace', '=', namespace).where('alias_key', '=', key).executeTakeFirst();
|
|
415
|
+
return row?.entry_id ?? null;
|
|
416
|
+
},
|
|
417
|
+
async setAliasEntryID (namespace, key, entryID) {
|
|
418
|
+
await db.insertInto('kubun_credential_aliases').values({
|
|
419
|
+
namespace,
|
|
420
|
+
alias_key: key,
|
|
421
|
+
entry_id: entryID
|
|
422
|
+
}).onConflict((oc)=>oc.columns([
|
|
423
|
+
'namespace',
|
|
424
|
+
'alias_key'
|
|
425
|
+
]).doUpdateSet({
|
|
426
|
+
entry_id: entryID
|
|
427
|
+
})).execute();
|
|
428
|
+
},
|
|
429
|
+
async deleteAliasEntryID (namespace, key) {
|
|
430
|
+
await db.deleteFrom('kubun_credential_aliases').where('namespace', '=', namespace).where('alias_key', '=', key).execute();
|
|
412
431
|
}
|
|
413
432
|
};
|
|
414
433
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ export { createCredentialStore } from './api.js';
|
|
|
5
5
|
export { credentialStoreDefinition } from './definition.js';
|
|
6
6
|
export declare const CREDENTIAL_STORE: "credential";
|
|
7
7
|
export declare function getCredentialStore(provider: StoreProvider): Promise<CredentialStoreAPI>;
|
|
8
|
-
export type { CredentialEntry, CredentialEntryTable, CredentialEntryWithProvenance, CredentialFactorDescriptor, CredentialKey, CredentialKeyBranch, CredentialKeyBranchTable, CredentialKeyState, CredentialKeyTable, CredentialOp, CredentialOpSubjectKind, CredentialOpTable, CredentialTables, CredentialWrapping, CredentialWrappingTable, CredentialWrappingWithBranch, InsertCredentialEntry, InsertCredentialKey, InsertCredentialOp, InsertCredentialWrapping, } from './tables.js';
|
|
8
|
+
export type { CredentialAlias, CredentialEntry, CredentialEntryTable, CredentialEntryWithProvenance, CredentialFactorDescriptor, CredentialKey, CredentialKeyBranch, CredentialKeyBranchTable, CredentialKeyState, CredentialKeyTable, CredentialOp, CredentialOpSubjectKind, CredentialOpTable, CredentialTables, CredentialWrapping, CredentialWrappingTable, CredentialWrappingWithBranch, InsertCredentialAlias, InsertCredentialEntry, InsertCredentialKey, InsertCredentialOp, InsertCredentialWrapping, KubunCredentialAliasTable, } from './tables.js';
|
package/lib/migrations.js
CHANGED
|
@@ -42,8 +42,16 @@ export function getCredentialMigrations(ctx) {
|
|
|
42
42
|
await db.schema.createIndex('idx_kubun_credential_ops_hlc').ifNotExists().on('kubun_credential_ops').columns([
|
|
43
43
|
'hlc'
|
|
44
44
|
]).execute();
|
|
45
|
+
// A plain local pointer, not an op subject — no hlc, no ops row, no
|
|
46
|
+
// merkle scan. Devices that resolve the same (namespace, key) converge on
|
|
47
|
+
// it locally, so it carries nothing to replicate.
|
|
48
|
+
await db.schema.createTable('kubun_credential_aliases').ifNotExists().addColumn('namespace', t.text, (col)=>col.notNull()).addColumn('alias_key', t.text, (col)=>col.notNull()).addColumn('entry_id', t.text, (col)=>col.notNull()).addColumn('created_at', t.timestamp, (col)=>col.defaultTo(now).notNull()).addPrimaryKeyConstraint('pk_kubun_credential_aliases', [
|
|
49
|
+
'namespace',
|
|
50
|
+
'alias_key'
|
|
51
|
+
]).execute();
|
|
45
52
|
},
|
|
46
53
|
async down (db) {
|
|
54
|
+
await db.schema.dropTable('kubun_credential_aliases').ifExists().execute();
|
|
47
55
|
await db.schema.dropTable('kubun_credential_ops').ifExists().execute();
|
|
48
56
|
await db.schema.dropTable('kubun_credential_entries').ifExists().execute();
|
|
49
57
|
await db.schema.dropTable('kubun_credential_wrappings').ifExists().execute();
|
package/lib/tables.d.ts
CHANGED
|
@@ -148,11 +148,30 @@ export type CredentialOpTable = {
|
|
|
148
148
|
};
|
|
149
149
|
export type CredentialOp = Selectable<CredentialOpTable>;
|
|
150
150
|
export type InsertCredentialOp = Insertable<CredentialOpTable>;
|
|
151
|
+
/**
|
|
152
|
+
* A local pointer from an opaque `(namespace, key)` to the entry id it
|
|
153
|
+
* currently names. Not an op subject: it carries no `hlc` and never appears in
|
|
154
|
+
* `kubun_credential_ops` or the merkle scan, because it is a per-device index
|
|
155
|
+
* rather than a replicated fact — each device that resolves the same
|
|
156
|
+
* `(namespace, key)` points it at the entry it converges on locally.
|
|
157
|
+
*
|
|
158
|
+
* The store does not interpret `namespace`, `alias_key` or `entry_id` — they
|
|
159
|
+
* are stored and returned verbatim, whatever a caller passes.
|
|
160
|
+
*/
|
|
161
|
+
export type KubunCredentialAliasTable = {
|
|
162
|
+
namespace: string;
|
|
163
|
+
alias_key: string;
|
|
164
|
+
entry_id: string;
|
|
165
|
+
created_at: CreatedAtColumn;
|
|
166
|
+
};
|
|
167
|
+
export type CredentialAlias = Selectable<KubunCredentialAliasTable>;
|
|
168
|
+
export type InsertCredentialAlias = Insertable<KubunCredentialAliasTable>;
|
|
151
169
|
export type CredentialTables = {
|
|
152
170
|
kubun_credential_keys: CredentialKeyTable;
|
|
153
171
|
kubun_credential_key_branches: CredentialKeyBranchTable;
|
|
154
172
|
kubun_credential_wrappings: CredentialWrappingTable;
|
|
155
173
|
kubun_credential_entries: CredentialEntryTable;
|
|
156
174
|
kubun_credential_ops: CredentialOpTable;
|
|
175
|
+
kubun_credential_aliases: KubunCredentialAliasTable;
|
|
157
176
|
};
|
|
158
177
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/store-credential",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"keywords": [],
|
|
5
5
|
"license": "see LICENSE.md",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@kokuin/token": "^0.5.0",
|
|
19
|
-
"
|
|
20
|
-
"@kubun/db": "^0.
|
|
21
|
-
"
|
|
19
|
+
"@kubun/db": "^0.14.0",
|
|
20
|
+
"@kubun/db-adapter": "^0.14.0",
|
|
21
|
+
"kysely": "^0.29.5"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"@kubun/db-postgres": "^0.
|
|
26
|
-
"@
|
|
24
|
+
"@kubun/db-better-sqlite": "^0.14.0",
|
|
25
|
+
"@kubun/db-postgres": "^0.14.0",
|
|
26
|
+
"@testcontainers/postgresql": "^12.1.0"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|