@e-sig/supabase 0.2.0 → 0.3.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Opendelphi contributors
3
+ Copyright (c) 2026 VMVTech, Ltd.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { SupabaseCertStore, type SupabaseCertStoreOptions, } from "./cert-store.js";
2
+ export { SupabasePqKeyStore, type SupabasePqKeyStoreOptions, } from "./pq-key-store.js";
2
3
  export { SupabaseAuditLogStore, type SupabaseAuditLogStoreOptions, } from "./audit-store.js";
3
4
  export { SupabasePdfStorageStore, type SupabasePdfStorageStoreOptions, } from "./storage.js";
4
5
  export { verifyAuditChain, type VerifyAuditChainOptions, type VerifyAuditChainResult, type AuditChainFailure, } from "./audit-chain.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,GAClC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,GAClC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  // @e-sig/supabase
2
2
  //
3
3
  // Supabase reference implementations of the @e-sig/core persistence
4
- // interfaces (CertStore, AuditLogStore, PdfStorageStore), plus the
4
+ // interfaces (CertStore, PqKeyStore, AuditLogStore, PdfStorageStore), plus the
5
5
  // verifyAuditChain() tamper-evidence checker for the audit hash chain. Pair
6
6
  // with the bundled migrations (migrations/0001_esig_self_contained.sql +
7
- // 0002_esig_audit_hashchain.sql). Table/bucket/tenant-column names are
8
- // configurable so you can map onto your existing schema.
7
+ // 0002_esig_audit_hashchain.sql + 0003_esig_pq_keys.sql). Table/bucket/
8
+ // tenant-column names are configurable so you can map onto your existing schema.
9
9
  export { SupabaseCertStore, } from "./cert-store.js";
10
+ export { SupabasePqKeyStore, } from "./pq-key-store.js";
10
11
  export { SupabaseAuditLogStore, } from "./audit-store.js";
11
12
  export { SupabasePdfStorageStore, } from "./storage.js";
12
13
  export { verifyAuditChain, } from "./audit-chain.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,EAAE;AACF,oEAAoE;AACpE,mEAAmE;AACnE,4EAA4E;AAC5E,yEAAyE;AACzE,uEAAuE;AACvE,yDAAyD;AAEzD,OAAO,EACL,iBAAiB,GAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,GAExB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,GAIjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,EAAE;AACF,oEAAoE;AACpE,+EAA+E;AAC/E,4EAA4E;AAC5E,yEAAyE;AACzE,wEAAwE;AACxE,iFAAiF;AAEjF,OAAO,EACL,iBAAiB,GAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,GAEnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,GAExB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,GAIjB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ import type { PqKeyStore, StoredPqKeys, PqPublicMaterial } from "@e-sig/core";
3
+ export interface SupabasePqKeyStoreOptions {
4
+ /** Table name. Default `org_pq_keys`. */
5
+ table?: string;
6
+ /** Tenant key column. Default `tenant_id`. */
7
+ tenantColumn?: string;
8
+ }
9
+ export declare class SupabasePqKeyStore implements PqKeyStore {
10
+ private sb;
11
+ private table;
12
+ private tenantColumn;
13
+ constructor(sb: SupabaseClient, opts?: SupabasePqKeyStoreOptions);
14
+ findActive(tenantId: string): Promise<StoredPqKeys | null>;
15
+ insert(input: {
16
+ tenantId: string;
17
+ keyBundleEncrypted: Uint8Array;
18
+ public: PqPublicMaterial;
19
+ rotatedFromId?: string | null;
20
+ }): Promise<StoredPqKeys>;
21
+ deactivate(id: string): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=pq-key-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pq-key-store.d.ts","sourceRoot":"","sources":["../src/pq-key-store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAgB9E,MAAM,WAAW,yBAAyB;IACxC,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0BD,qBAAa,kBAAmB,YAAW,UAAU;IAGvC,OAAO,CAAC,EAAE;IAFtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAS;gBACT,EAAE,EAAE,cAAc,EAAE,IAAI,GAAE,yBAA8B;IAKtE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAW1D,MAAM,CAAC,KAAK,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,kBAAkB,EAAE,UAAU,CAAC;QAC/B,MAAM,EAAE,gBAAgB,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,GAAG,OAAO,CAAC,YAAY,CAAC;IAwBnB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C"}
@@ -0,0 +1,82 @@
1
+ // @e-sig/supabase — SupabasePqKeyStore
2
+ //
3
+ // PqKeyStore backed by a Postgres table (default `org_pq_keys`) via supabase-js.
4
+ // Matches migrations/0003_esig_pq_keys.sql. Drive it with ensureActivePqKeys /
5
+ // rotatePqKeys from @e-sig/core. Mirrors SupabaseCertStore, including the bytea
6
+ // `\x<hex>` wire-encoding workaround for the encrypted bundle.
7
+ /** Decode a Postgres bytea (`\x<hex>` from PostgREST, or already-bytes) to a Uint8Array. */
8
+ function decodeBytea(raw) {
9
+ if (raw instanceof Uint8Array)
10
+ return raw;
11
+ if (typeof raw === "string" && raw.startsWith("\\x"))
12
+ return Buffer.from(raw.slice(2), "hex");
13
+ if (typeof raw === "string")
14
+ return Buffer.from(raw, "base64");
15
+ return new Uint8Array();
16
+ }
17
+ function toStoredPqKeys(r, tenantColumn) {
18
+ const tenantId = r[tenantColumn] ?? r.tenant_id ?? r.org_id ?? "";
19
+ return {
20
+ id: r.id,
21
+ tenantId,
22
+ keyBundleEncrypted: decodeBytea(r.key_bundle_encrypted),
23
+ ed25519Public: r.ed25519_public,
24
+ mldsa65Public: r.mldsa65_public,
25
+ mldsa65Fpr: r.mldsa65_fpr,
26
+ keyId: r.key_id,
27
+ active: r.active,
28
+ rotatedFromId: r.rotated_from,
29
+ createdAt: new Date(r.created_at),
30
+ };
31
+ }
32
+ export class SupabasePqKeyStore {
33
+ sb;
34
+ table;
35
+ tenantColumn;
36
+ constructor(sb, opts = {}) {
37
+ this.sb = sb;
38
+ this.table = opts.table ?? "org_pq_keys";
39
+ this.tenantColumn = opts.tenantColumn ?? "tenant_id";
40
+ }
41
+ async findActive(tenantId) {
42
+ const { data, error } = await this.sb
43
+ .from(this.table)
44
+ .select("*")
45
+ .eq(this.tenantColumn, tenantId)
46
+ .eq("active", true)
47
+ .maybeSingle();
48
+ if (error)
49
+ throw new Error(`SupabasePqKeyStore.findActive: ${error.message}`);
50
+ return data ? toStoredPqKeys(data, this.tenantColumn) : null;
51
+ }
52
+ async insert(input) {
53
+ // bytea wire encoding: supabase-js JSON-stringifies a Uint8Array, mangling
54
+ // the round-trip. Pre-encode as Postgres bytea-in hex form `\x<hex>`.
55
+ const bytes = Buffer.isBuffer(input.keyBundleEncrypted)
56
+ ? input.keyBundleEncrypted
57
+ : Buffer.from(input.keyBundleEncrypted);
58
+ const hexEncoded = "\\x" + bytes.toString("hex");
59
+ const { data, error } = await this.sb
60
+ .from(this.table)
61
+ .insert({
62
+ [this.tenantColumn]: input.tenantId,
63
+ key_bundle_encrypted: hexEncoded,
64
+ ed25519_public: input.public.ed25519,
65
+ mldsa65_public: input.public.mldsa65,
66
+ mldsa65_fpr: input.public.mldsa65Fpr,
67
+ key_id: input.public.keyId,
68
+ rotated_from: input.rotatedFromId ?? null,
69
+ })
70
+ .select()
71
+ .single();
72
+ if (error || !data)
73
+ throw new Error(`SupabasePqKeyStore.insert: ${error?.message}`);
74
+ return toStoredPqKeys(data, this.tenantColumn);
75
+ }
76
+ async deactivate(id) {
77
+ const { error } = await this.sb.from(this.table).update({ active: false }).eq("id", id);
78
+ if (error)
79
+ throw new Error(`SupabasePqKeyStore.deactivate: ${error.message}`);
80
+ }
81
+ }
82
+ //# sourceMappingURL=pq-key-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pq-key-store.js","sourceRoot":"","sources":["../src/pq-key-store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@e-sig/supabase",
3
- "version": "0.2.0",
4
- "description": "Supabase adapters (CertStore / AuditLogStore / PdfStorageStore) for @e-sig/core self-contained PDF e-signature persistence on Supabase Postgres + Storage.",
3
+ "version": "0.3.1",
4
+ "description": "Supabase adapters (CertStore / AuditLogStore / PdfStorageStore) for @e-sig/core \u2014 self-contained PDF e-signature persistence on Supabase Postgres + Storage.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -48,14 +48,14 @@
48
48
  "homepage": "https://github.com/vmvtech/esig-suite/tree/main/packages/esig-supabase#readme",
49
49
  "peerDependencies": {
50
50
  "@supabase/supabase-js": ">=2",
51
- "@e-sig/core": "^0.4.0 || ^0.5.0"
51
+ "@e-sig/core": "^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@supabase/supabase-js": "^2.98.0",
55
55
  "@types/node": "^22.0.0",
56
- "@e-sig/core": "^0.5.0",
56
+ "@e-sig/core": "^0.7.0",
57
57
  "typescript": "^5.4.0",
58
- "vitest": "^2.1.9"
58
+ "vitest": "^4.1.10"
59
59
  },
60
60
  "publishConfig": {
61
61
  "registry": "https://registry.npmjs.org",