@arcblock/did-connect-service 4.1.21 → 4.1.23

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.
Files changed (173) hide show
  1. package/dist/_generated/asset-bytes.js +1 -1
  2. package/dist/_generated/asset-manifest.js +3 -3
  3. package/dist/assets/admin-core.1fc3260c.js +1623 -0
  4. package/dist/assets/admin-core.5a2d69b0.js +2067 -0
  5. package/dist/assets/admin-core.9fff6042.js +2083 -0
  6. package/dist/assets/admin-core.a13c2729.js +1461 -0
  7. package/dist/assets/{admin-core.40671087.js → admin-core.a63bbc69.js} +2 -12
  8. package/dist/assets/admin-core.c0b5af61.js +1393 -0
  9. package/dist/assets/admin-core.cbbdbe6d.js +1465 -0
  10. package/dist/assets/admin-core.e83fd379.js +1397 -0
  11. package/dist/assets/admin-extra.143b5774.js +2543 -0
  12. package/dist/assets/admin-extra.35b91f98.js +2543 -0
  13. package/dist/assets/admin-extra.531b187f.js +2552 -0
  14. package/dist/assets/admin-extra.7ca9c16b.js +2529 -0
  15. package/dist/assets/admin-extra.841b2bbe.js +2530 -0
  16. package/dist/assets/admin-extra.afcb3651.js +2528 -0
  17. package/dist/assets/admin.7c5d5f04.css +2312 -0
  18. package/dist/assets/admin.c26bb17a.css +2219 -0
  19. package/dist/assets/login.4404e695.js +720 -0
  20. package/dist/assets/login.bb9f8b03.js +720 -0
  21. package/dist/assets/login.d3f05790.js +720 -0
  22. package/dist/assets/login.fa25f37a.js +720 -0
  23. package/dist/blocklet-service-rpc.d.ts.map +1 -1
  24. package/dist/blocklet-service-rpc.js +11 -8
  25. package/dist/blocklet-service-rpc.js.map +1 -1
  26. package/dist/blocklet-service.d.ts +11 -8
  27. package/dist/blocklet-service.d.ts.map +1 -1
  28. package/dist/blocklet-service.js +32 -38
  29. package/dist/blocklet-service.js.map +1 -1
  30. package/dist/embedded.d.ts +6 -0
  31. package/dist/embedded.d.ts.map +1 -1
  32. package/dist/embedded.js +1 -0
  33. package/dist/embedded.js.map +1 -1
  34. package/dist/handlers/account-merge-handler.d.ts +63 -0
  35. package/dist/handlers/account-merge-handler.d.ts.map +1 -0
  36. package/dist/handlers/account-merge-handler.js +263 -0
  37. package/dist/handlers/account-merge-handler.js.map +1 -0
  38. package/dist/handlers/auth-handler.d.ts +9 -5
  39. package/dist/handlers/auth-handler.d.ts.map +1 -1
  40. package/dist/handlers/auth-handler.js +28 -7
  41. package/dist/handlers/auth-handler.js.map +1 -1
  42. package/dist/handlers/blocklet-js-handler.d.ts +3 -2
  43. package/dist/handlers/blocklet-js-handler.d.ts.map +1 -1
  44. package/dist/handlers/blocklet-js-handler.js +4 -2
  45. package/dist/handlers/blocklet-js-handler.js.map +1 -1
  46. package/dist/handlers/branding-handler.d.ts +4 -0
  47. package/dist/handlers/branding-handler.d.ts.map +1 -1
  48. package/dist/handlers/branding-handler.js +12 -6
  49. package/dist/handlers/branding-handler.js.map +1 -1
  50. package/dist/handlers/cimd.d.ts +6 -1
  51. package/dist/handlers/cimd.d.ts.map +1 -1
  52. package/dist/handlers/cimd.js +12 -2
  53. package/dist/handlers/cimd.js.map +1 -1
  54. package/dist/handlers/did-connect-handler.d.ts +22 -0
  55. package/dist/handlers/did-connect-handler.d.ts.map +1 -1
  56. package/dist/handlers/did-connect-handler.js +191 -17
  57. package/dist/handlers/did-connect-handler.js.map +1 -1
  58. package/dist/handlers/email-login-handler.d.ts +2 -0
  59. package/dist/handlers/email-login-handler.d.ts.map +1 -1
  60. package/dist/handlers/email-login-handler.js +30 -14
  61. package/dist/handlers/email-login-handler.js.map +1 -1
  62. package/dist/handlers/oauth-handler.d.ts +15 -0
  63. package/dist/handlers/oauth-handler.d.ts.map +1 -1
  64. package/dist/handlers/oauth-handler.js +107 -43
  65. package/dist/handlers/oauth-handler.js.map +1 -1
  66. package/dist/handlers/passkey-handler.d.ts.map +1 -1
  67. package/dist/handlers/passkey-handler.js +40 -8
  68. package/dist/handlers/passkey-handler.js.map +1 -1
  69. package/dist/handlers/team-handler.d.ts +1 -1
  70. package/dist/handlers/team-handler.d.ts.map +1 -1
  71. package/dist/handlers/team-handler.js +43 -3
  72. package/dist/handlers/team-handler.js.map +1 -1
  73. package/dist/handlers/ticket-handler.d.ts.map +1 -1
  74. package/dist/handlers/ticket-handler.js +4 -2
  75. package/dist/handlers/ticket-handler.js.map +1 -1
  76. package/dist/handlers/unbind-account.d.ts +22 -0
  77. package/dist/handlers/unbind-account.d.ts.map +1 -0
  78. package/dist/handlers/unbind-account.js +20 -0
  79. package/dist/handlers/unbind-account.js.map +1 -0
  80. package/dist/http/security-headers.d.ts +38 -0
  81. package/dist/http/security-headers.d.ts.map +1 -0
  82. package/dist/http/security-headers.js +67 -0
  83. package/dist/http/security-headers.js.map +1 -0
  84. package/dist/identity/account-state.d.ts +37 -0
  85. package/dist/identity/account-state.d.ts.map +1 -0
  86. package/dist/identity/account-state.js +97 -0
  87. package/dist/identity/account-state.js.map +1 -0
  88. package/dist/identity/json-content-type.d.ts +14 -0
  89. package/dist/identity/json-content-type.d.ts.map +1 -0
  90. package/dist/identity/json-content-type.js +26 -0
  91. package/dist/identity/json-content-type.js.map +1 -0
  92. package/dist/index.d.ts +3 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +2 -2
  95. package/dist/index.js.map +1 -1
  96. package/dist/oauth-adapters/apple.d.ts +1 -1
  97. package/dist/oauth-adapters/apple.d.ts.map +1 -1
  98. package/dist/oauth-adapters/apple.js +2 -0
  99. package/dist/oauth-adapters/apple.js.map +1 -1
  100. package/dist/oauth-adapters/auth0-legacy.d.ts +1 -1
  101. package/dist/oauth-adapters/auth0-legacy.d.ts.map +1 -1
  102. package/dist/oauth-adapters/auth0-legacy.js +2 -0
  103. package/dist/oauth-adapters/auth0-legacy.js.map +1 -1
  104. package/dist/oauth-adapters/auth0.d.ts +1 -1
  105. package/dist/oauth-adapters/auth0.d.ts.map +1 -1
  106. package/dist/oauth-adapters/auth0.js +2 -0
  107. package/dist/oauth-adapters/auth0.js.map +1 -1
  108. package/dist/oauth-adapters/github.d.ts.map +1 -1
  109. package/dist/oauth-adapters/github.js +19 -12
  110. package/dist/oauth-adapters/github.js.map +1 -1
  111. package/dist/oauth-adapters/google.d.ts +1 -1
  112. package/dist/oauth-adapters/google.d.ts.map +1 -1
  113. package/dist/oauth-adapters/google.js +2 -0
  114. package/dist/oauth-adapters/google.js.map +1 -1
  115. package/dist/oauth-adapters/types.d.ts +7 -0
  116. package/dist/oauth-adapters/types.d.ts.map +1 -1
  117. package/dist/oauth-adapters/types.js +4 -1
  118. package/dist/oauth-adapters/types.js.map +1 -1
  119. package/dist/package-branding.d.ts +18 -0
  120. package/dist/package-branding.d.ts.map +1 -0
  121. package/dist/package-branding.js +103 -0
  122. package/dist/package-branding.js.map +1 -0
  123. package/dist/pages/admin/i18n.d.ts.map +1 -1
  124. package/dist/pages/admin/i18n.js +86 -0
  125. package/dist/pages/admin/i18n.js.map +1 -1
  126. package/dist/pages/admin/index.d.ts +4 -0
  127. package/dist/pages/admin/index.d.ts.map +1 -1
  128. package/dist/pages/admin/index.js +10 -2
  129. package/dist/pages/admin/index.js.map +1 -1
  130. package/dist/pages/admin/merge-confirm-view.d.ts +48 -0
  131. package/dist/pages/admin/merge-confirm-view.d.ts.map +1 -0
  132. package/dist/pages/admin/merge-confirm-view.js +85 -0
  133. package/dist/pages/admin/merge-confirm-view.js.map +1 -0
  134. package/dist/pages/admin/merge-method-picker.d.ts +12 -0
  135. package/dist/pages/admin/merge-method-picker.d.ts.map +1 -0
  136. package/dist/pages/admin/merge-method-picker.js +34 -0
  137. package/dist/pages/admin/merge-method-picker.js.map +1 -0
  138. package/dist/pages/admin/oauth-popup-close.d.ts +13 -0
  139. package/dist/pages/admin/oauth-popup-close.d.ts.map +1 -0
  140. package/dist/pages/admin/oauth-popup-close.js +15 -0
  141. package/dist/pages/admin/oauth-popup-close.js.map +1 -0
  142. package/dist/pages/admin/styles.d.ts +1 -1
  143. package/dist/pages/admin/styles.d.ts.map +1 -1
  144. package/dist/pages/admin/styles.js +83 -0
  145. package/dist/pages/admin/styles.js.map +1 -1
  146. package/dist/pages/admin/tab-audit.d.ts +1 -1
  147. package/dist/pages/admin/tab-audit.d.ts.map +1 -1
  148. package/dist/pages/admin/tab-audit.js +12 -0
  149. package/dist/pages/admin/tab-audit.js.map +1 -1
  150. package/dist/pages/admin/tab-profile-accounts.d.ts.map +1 -1
  151. package/dist/pages/admin/tab-profile-accounts.js +509 -3
  152. package/dist/pages/admin/tab-profile-accounts.js.map +1 -1
  153. package/dist/pages/invite-page.d.ts +1 -0
  154. package/dist/pages/invite-page.d.ts.map +1 -1
  155. package/dist/pages/invite-page.js +13 -3
  156. package/dist/pages/invite-page.js.map +1 -1
  157. package/dist/store/account-merge.d.ts +167 -0
  158. package/dist/store/account-merge.d.ts.map +1 -0
  159. package/dist/store/account-merge.js +313 -0
  160. package/dist/store/account-merge.js.map +1 -0
  161. package/dist/store/d1-store.d.ts +97 -7
  162. package/dist/store/d1-store.d.ts.map +1 -1
  163. package/dist/store/d1-store.js +421 -23
  164. package/dist/store/d1-store.js.map +1 -1
  165. package/dist/types.d.ts +8 -0
  166. package/dist/types.d.ts.map +1 -1
  167. package/migrations/0015_connected_accounts_id_index.sql +6 -0
  168. package/migrations/0016_did_aliases.sql +11 -0
  169. package/migrations/0017_unbind_revoke_and_cascade.sql +49 -0
  170. package/migrations/0018_primary_credential_did.sql +54 -0
  171. package/migrations/0019_account_merge.sql +16 -0
  172. package/migrations/0020_dedupe_connected_accounts.sql +24 -0
  173. package/package.json +3 -3
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Account-merge store operations (#149). Writers flatten aliases and keep
3
+ * the higher `roleLevel()` membership per instance. Callers pass a D1
4
+ * database; D1Store wraps these and invalidates membership cache.
5
+ */
6
+ export declare const MERGE_START_TTL_SECONDS: number;
7
+ export declare const MERGE_INTENT_TTL_MS: number;
8
+ export declare const MERGE_START_CACHE_PREFIX = "merge-start:";
9
+ /** Refuse a single merge batch that would monopolize D1 (#174). */
10
+ export declare const MERGE_BATCH_MAX_STATEMENTS = 800;
11
+ /** Fixed statements in every merge batch: alias insert, flatten, revoke A, revoke B, mark A, bump B. */
12
+ export declare const MERGE_BATCH_FIXED_STATEMENTS = 6;
13
+ export declare const MERGE_TOO_LARGE_ERROR = "Merge touches too many rows; split the accounts or handle this merge manually";
14
+ /** Stable host-side warning codes. User copy lives in i18n.ts (#189). */
15
+ export declare const MERGE_HOST_WARNINGS: readonly ["blocklet-owner-clash", "external-token-rebind"];
16
+ export type MergeHostWarningCode = (typeof MERGE_HOST_WARNINGS)[number];
17
+ export interface MergeCredential {
18
+ did: string;
19
+ provider: string;
20
+ id: string | null;
21
+ }
22
+ export interface MergeSkippedConflict extends MergeCredential {
23
+ reason: string;
24
+ }
25
+ export interface MergeMovedMembership {
26
+ instanceDid: string;
27
+ role: string;
28
+ invitedBy: string | null;
29
+ createdAt: string | null;
30
+ createdBy: string | null;
31
+ }
32
+ export interface MergeMergedMembership {
33
+ instanceDid: string;
34
+ fromRole: string;
35
+ intoRoleBefore: string;
36
+ keptRole: string;
37
+ fromRow: MergeMovedMembership;
38
+ }
39
+ export interface MergeAccessKey {
40
+ accessKeyId: string;
41
+ createdBy: string;
42
+ }
43
+ export interface MergeAliasCreated {
44
+ did: string;
45
+ canonicalDid: string;
46
+ reason: "merged";
47
+ }
48
+ export interface MergeAliasRewritten {
49
+ did: string;
50
+ fromCanonicalDid: string;
51
+ toCanonicalDid: string;
52
+ }
53
+ export interface MergeIntoRole {
54
+ instanceDid: string;
55
+ role: string;
56
+ }
57
+ export interface MergeSnapshot {
58
+ fromDid: string;
59
+ intoDid: string;
60
+ credentials: MergeCredential[];
61
+ skippedConflicts: MergeSkippedConflict[];
62
+ memberships: {
63
+ moved: MergeMovedMembership[];
64
+ merged: MergeMergedMembership[];
65
+ };
66
+ accessKeys: MergeAccessKey[];
67
+ aliasesCreated: MergeAliasCreated[];
68
+ aliasesRewritten: MergeAliasRewritten[];
69
+ intoPreMergeRoles: MergeIntoRole[];
70
+ didSpace: {
71
+ copied: false;
72
+ pointer: string;
73
+ };
74
+ hostWarnings: MergeHostWarningCode[];
75
+ fromPrimaryCredentialDid: string | null;
76
+ fromPasskeyCount: number;
77
+ intoPasskeyCount: number;
78
+ movedPasskeyCount: number;
79
+ }
80
+ export interface MergeIntentRow {
81
+ tokenHash: string;
82
+ fromDid: string;
83
+ intoDid: string;
84
+ expiresAt: string;
85
+ usedAt: string | null;
86
+ }
87
+ export interface MergePlanView {
88
+ fromDid: string;
89
+ intoDid: string;
90
+ credentials: MergeCredential[];
91
+ skippedConflicts: MergeSkippedConflict[];
92
+ memberships: MergeSnapshot["memberships"];
93
+ accessKeys: MergeAccessKey[];
94
+ aliasesCreated: MergeAliasCreated[];
95
+ aliasesRewritten: MergeAliasRewritten[];
96
+ intoPreMergeRoles: MergeIntoRole[];
97
+ didSpace: {
98
+ copied: false;
99
+ pointer: string;
100
+ };
101
+ hostWarnings: MergeHostWarningCode[];
102
+ }
103
+ /**
104
+ * Dry-run payload for the confirm page (#189). Counts + provider/role lists;
105
+ * no credential id, instanceDid, or accessKeyId (#176).
106
+ */
107
+ export interface MergeConfirmPlan {
108
+ fromDid: string;
109
+ intoDid: string;
110
+ credentialCount: number;
111
+ credentialsByProvider: Array<{
112
+ provider: string;
113
+ }>;
114
+ skippedConflictCount: number;
115
+ skippedConflicts: Array<{
116
+ provider: string;
117
+ reason: string;
118
+ }>;
119
+ membershipMovedCount: number;
120
+ membershipMergedCount: number;
121
+ membershipChanges: Array<{
122
+ fromRole: string;
123
+ intoRoleBefore: string;
124
+ keptRole: string;
125
+ }>;
126
+ accessKeyCount: number;
127
+ aliasCreatedCount: number;
128
+ aliasRewrittenCount: number;
129
+ didSpace: {
130
+ copied: false;
131
+ pointer: string;
132
+ };
133
+ hostWarningCodes: MergeHostWarningCode[];
134
+ tooLarge: boolean;
135
+ }
136
+ export declare function mergeStartCacheKey(tokenHash: string): string;
137
+ export declare function didSpacePointer(fromDid: string): string;
138
+ export declare function higherRole(a: string, b: string): string;
139
+ export declare function createMergeStartChallenge(): Promise<{
140
+ challenge: string;
141
+ tokenHash: string;
142
+ expiresAt: string;
143
+ }>;
144
+ export declare function createMergeIntentToken(): Promise<{
145
+ token: string;
146
+ tokenHash: string;
147
+ expiresAt: string;
148
+ }>;
149
+ export declare function hashMergeToken(token: string): Promise<string>;
150
+ export declare function insertMergeIntent(db: D1Database, input: {
151
+ tokenHash: string;
152
+ fromDid: string;
153
+ intoDid: string;
154
+ expiresAt: string;
155
+ }): Promise<void>;
156
+ export declare function getMergeIntentByHash(db: D1Database, tokenHash: string): Promise<MergeIntentRow | null>;
157
+ export declare function intentIsUsable(intent: MergeIntentRow, now?: number): "ok" | "used" | "expired";
158
+ export declare function consumeMergeIntent(db: D1Database, tokenHash: string, usedAt: string): Promise<boolean>;
159
+ export declare function buildMergeSnapshot(db: D1Database, fromDid: string, intoDid: string): Promise<MergeSnapshot>;
160
+ export declare function toMergePlanView(snapshot: MergeSnapshot): MergePlanView;
161
+ export declare function willMovePrimaryCredential(snapshot: MergeSnapshot): boolean;
162
+ /** Same formula `commitMergeBatch` uses to size the D1 batch (#189). */
163
+ export declare function countMergeStatements(snapshot: MergeSnapshot): number;
164
+ export declare function toMergeConfirmPlan(snapshot: MergeSnapshot): MergeConfirmPlan;
165
+ export declare function commitMergeBatch(db: D1Database, snapshot: MergeSnapshot, now: string): Promise<void>;
166
+ export declare function hashSnapshot(snapshot: MergeSnapshot): Promise<string>;
167
+ //# sourceMappingURL=account-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-merge.d.ts","sourceRoot":"","sources":["../../src/store/account-merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Account-merge store operations (#149). Writers flatten aliases and keep
3
+ * the higher `roleLevel()` membership per instance. Callers pass a D1
4
+ * database; D1Store wraps these and invalidates membership cache.
5
+ */
6
+ import { roleLevel } from "../access/rbac.js";
7
+ import { hashRefreshToken } from "../identity/refresh-tokens.js";
8
+ const FLATTEN_DID_ALIASES_SQL = "UPDATE cs_did_aliases SET canonicalDid = ? WHERE canonicalDid = ?";
9
+ export const MERGE_START_TTL_SECONDS = 10 * 60;
10
+ export const MERGE_INTENT_TTL_MS = 10 * 60 * 1000;
11
+ export const MERGE_START_CACHE_PREFIX = "merge-start:";
12
+ /** Refuse a single merge batch that would monopolize D1 (#174). */
13
+ export const MERGE_BATCH_MAX_STATEMENTS = 800;
14
+ /** Fixed statements in every merge batch: alias insert, flatten, revoke A, revoke B, mark A, bump B. */
15
+ export const MERGE_BATCH_FIXED_STATEMENTS = 6;
16
+ export const MERGE_TOO_LARGE_ERROR = "Merge touches too many rows; split the accounts or handle this merge manually";
17
+ /** Stable host-side warning codes. User copy lives in i18n.ts (#189). */
18
+ export const MERGE_HOST_WARNINGS = ["blocklet-owner-clash", "external-token-rebind"];
19
+ function randomToken() {
20
+ const bytes = new Uint8Array(32);
21
+ crypto.getRandomValues(bytes);
22
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
23
+ }
24
+ export function mergeStartCacheKey(tokenHash) {
25
+ return `${MERGE_START_CACHE_PREFIX}${tokenHash}`;
26
+ }
27
+ export function didSpacePointer(fromDid) {
28
+ return `/user/.archive/${fromDid}/`;
29
+ }
30
+ export function higherRole(a, b) {
31
+ return roleLevel(a) >= roleLevel(b) ? a : b;
32
+ }
33
+ export async function createMergeStartChallenge() {
34
+ const challenge = randomToken();
35
+ const tokenHash = await hashRefreshToken(challenge);
36
+ const expiresAt = new Date(Date.now() + MERGE_START_TTL_SECONDS * 1000).toISOString();
37
+ return { challenge, tokenHash, expiresAt };
38
+ }
39
+ export async function createMergeIntentToken() {
40
+ const token = randomToken();
41
+ const tokenHash = await hashRefreshToken(token);
42
+ const expiresAt = new Date(Date.now() + MERGE_INTENT_TTL_MS).toISOString();
43
+ return { token, tokenHash, expiresAt };
44
+ }
45
+ export async function hashMergeToken(token) {
46
+ return hashRefreshToken(token);
47
+ }
48
+ export async function insertMergeIntent(db, input) {
49
+ await db
50
+ .prepare(`INSERT INTO cs_merge_intents (tokenHash, fromDid, intoDid, expiresAt, usedAt)
51
+ VALUES (?, ?, ?, ?, NULL)`)
52
+ .bind(input.tokenHash, input.fromDid, input.intoDid, input.expiresAt)
53
+ .run();
54
+ }
55
+ export async function getMergeIntentByHash(db, tokenHash) {
56
+ return ((await db
57
+ .prepare("SELECT tokenHash, fromDid, intoDid, expiresAt, usedAt FROM cs_merge_intents WHERE tokenHash = ?")
58
+ .bind(tokenHash)
59
+ .first()) ?? null);
60
+ }
61
+ export function intentIsUsable(intent, now = Date.now()) {
62
+ if (intent.usedAt)
63
+ return "used";
64
+ if (new Date(intent.expiresAt).getTime() <= now)
65
+ return "expired";
66
+ return "ok";
67
+ }
68
+ export async function consumeMergeIntent(db, tokenHash, usedAt) {
69
+ await db
70
+ .prepare(`UPDATE cs_merge_intents SET usedAt = ?
71
+ WHERE tokenHash = ? AND usedAt IS NULL AND expiresAt > ?`)
72
+ .bind(usedAt, tokenHash, usedAt)
73
+ .run();
74
+ const row = await db
75
+ .prepare("SELECT usedAt FROM cs_merge_intents WHERE tokenHash = ?")
76
+ .bind(tokenHash)
77
+ .first();
78
+ return row?.usedAt === usedAt;
79
+ }
80
+ async function listConnected(db, userDid) {
81
+ const rows = await db
82
+ .prepare("SELECT did, provider, id, userDid FROM cs_connected_accounts WHERE userDid = ?")
83
+ .bind(userDid)
84
+ .all();
85
+ return rows.results ?? [];
86
+ }
87
+ async function listMembershipsForUser(db, userDid) {
88
+ const rows = await db
89
+ .prepare("SELECT user_did, instance_did, role, invited_by, created_at, created_by FROM cs_memberships WHERE user_did = ?")
90
+ .bind(userDid)
91
+ .all();
92
+ return rows.results ?? [];
93
+ }
94
+ async function listAccessKeysByCreator(db, createdBy) {
95
+ const rows = await db
96
+ .prepare("SELECT accessKeyId, createdBy FROM cs_access_keys WHERE createdBy = ?")
97
+ .bind(createdBy)
98
+ .all();
99
+ return rows.results ?? [];
100
+ }
101
+ async function listAliasesPointingAt(db, canonicalDid) {
102
+ const rows = await db
103
+ .prepare("SELECT did, canonicalDid FROM cs_did_aliases WHERE canonicalDid = ?")
104
+ .bind(canonicalDid)
105
+ .all();
106
+ return rows.results ?? [];
107
+ }
108
+ export async function buildMergeSnapshot(db, fromDid, intoDid) {
109
+ const [fromAccounts, intoAccounts, fromMemberships, intoMemberships, accessKeys, ancestorAliases, fromUser, intoUser] = await Promise.all([
110
+ listConnected(db, fromDid),
111
+ listConnected(db, intoDid),
112
+ listMembershipsForUser(db, fromDid),
113
+ listMembershipsForUser(db, intoDid),
114
+ listAccessKeysByCreator(db, fromDid),
115
+ listAliasesPointingAt(db, fromDid),
116
+ db
117
+ .prepare("SELECT primaryCredentialDid, passkeyCount FROM cs_users WHERE did = ?")
118
+ .bind(fromDid)
119
+ .first(),
120
+ db
121
+ .prepare("SELECT passkeyCount FROM cs_users WHERE did = ?")
122
+ .bind(intoDid)
123
+ .first(),
124
+ ]);
125
+ const intoByProviderId = new Set(intoAccounts.filter((a) => a.provider && a.id).map((a) => `${a.provider}\0${a.id}`));
126
+ const credentials = [];
127
+ const skippedConflicts = [];
128
+ for (const account of fromAccounts) {
129
+ const key = account.provider && account.id ? `${account.provider}\0${account.id}` : "";
130
+ if (key && intoByProviderId.has(key)) {
131
+ skippedConflicts.push({
132
+ did: account.did,
133
+ provider: account.provider,
134
+ id: account.id,
135
+ reason: "UNIQUE(provider,id)",
136
+ });
137
+ continue;
138
+ }
139
+ credentials.push({ did: account.did, provider: account.provider, id: account.id });
140
+ }
141
+ const intoByInstance = new Map(intoMemberships.map((m) => [m.instance_did, m]));
142
+ const moved = [];
143
+ const merged = [];
144
+ for (const row of fromMemberships) {
145
+ const existing = intoByInstance.get(row.instance_did);
146
+ const fromRow = {
147
+ instanceDid: row.instance_did,
148
+ role: row.role,
149
+ invitedBy: row.invited_by,
150
+ createdAt: row.created_at,
151
+ createdBy: row.created_by,
152
+ };
153
+ if (!existing) {
154
+ moved.push(fromRow);
155
+ continue;
156
+ }
157
+ merged.push({
158
+ instanceDid: row.instance_did,
159
+ fromRole: row.role,
160
+ intoRoleBefore: existing.role,
161
+ keptRole: higherRole(row.role, existing.role),
162
+ fromRow,
163
+ });
164
+ }
165
+ const intoPreMergeRoles = intoMemberships.map((m) => ({
166
+ instanceDid: m.instance_did,
167
+ role: m.role,
168
+ }));
169
+ const aliasesCreated = [{ did: fromDid, canonicalDid: intoDid, reason: "merged" }];
170
+ const aliasesRewritten = ancestorAliases
171
+ .filter((row) => row.did !== fromDid)
172
+ .map((row) => ({
173
+ did: row.did,
174
+ fromCanonicalDid: row.canonicalDid,
175
+ toCanonicalDid: intoDid,
176
+ }));
177
+ const movedPasskeyCount = credentials.filter((c) => c.provider === "passkey").length;
178
+ return {
179
+ fromDid,
180
+ intoDid,
181
+ credentials,
182
+ skippedConflicts,
183
+ memberships: { moved, merged },
184
+ accessKeys,
185
+ aliasesCreated,
186
+ aliasesRewritten,
187
+ intoPreMergeRoles,
188
+ didSpace: { copied: false, pointer: didSpacePointer(fromDid) },
189
+ hostWarnings: [...MERGE_HOST_WARNINGS],
190
+ fromPrimaryCredentialDid: fromUser?.primaryCredentialDid ?? null,
191
+ fromPasskeyCount: Number(fromUser?.passkeyCount ?? 0),
192
+ intoPasskeyCount: Number(intoUser?.passkeyCount ?? 0),
193
+ movedPasskeyCount,
194
+ };
195
+ }
196
+ export function toMergePlanView(snapshot) {
197
+ return {
198
+ fromDid: snapshot.fromDid,
199
+ intoDid: snapshot.intoDid,
200
+ credentials: snapshot.credentials,
201
+ skippedConflicts: snapshot.skippedConflicts,
202
+ memberships: snapshot.memberships,
203
+ accessKeys: snapshot.accessKeys,
204
+ aliasesCreated: snapshot.aliasesCreated,
205
+ aliasesRewritten: snapshot.aliasesRewritten,
206
+ intoPreMergeRoles: snapshot.intoPreMergeRoles,
207
+ didSpace: snapshot.didSpace,
208
+ hostWarnings: snapshot.hostWarnings,
209
+ };
210
+ }
211
+ export function willMovePrimaryCredential(snapshot) {
212
+ return Boolean(snapshot.fromPrimaryCredentialDid &&
213
+ snapshot.credentials.some((c) => c.did === snapshot.fromPrimaryCredentialDid));
214
+ }
215
+ /** Same formula `commitMergeBatch` uses to size the D1 batch (#189). */
216
+ export function countMergeStatements(snapshot) {
217
+ return (snapshot.credentials.length +
218
+ (willMovePrimaryCredential(snapshot) ? 1 : 0) +
219
+ snapshot.memberships.moved.length +
220
+ 2 * snapshot.memberships.merged.length +
221
+ snapshot.accessKeys.length +
222
+ MERGE_BATCH_FIXED_STATEMENTS);
223
+ }
224
+ export function toMergeConfirmPlan(snapshot) {
225
+ return {
226
+ fromDid: snapshot.fromDid,
227
+ intoDid: snapshot.intoDid,
228
+ credentialCount: snapshot.credentials.length,
229
+ credentialsByProvider: snapshot.credentials.map((c) => ({ provider: c.provider })),
230
+ skippedConflictCount: snapshot.skippedConflicts.length,
231
+ skippedConflicts: snapshot.skippedConflicts.map((row) => ({
232
+ provider: row.provider,
233
+ reason: row.reason,
234
+ })),
235
+ membershipMovedCount: snapshot.memberships.moved.length,
236
+ membershipMergedCount: snapshot.memberships.merged.length,
237
+ membershipChanges: snapshot.memberships.merged.map((row) => ({
238
+ fromRole: row.fromRole,
239
+ intoRoleBefore: row.intoRoleBefore,
240
+ keptRole: row.keptRole,
241
+ })),
242
+ accessKeyCount: snapshot.accessKeys.length,
243
+ aliasCreatedCount: snapshot.aliasesCreated.length,
244
+ aliasRewrittenCount: snapshot.aliasesRewritten.length,
245
+ didSpace: snapshot.didSpace,
246
+ hostWarningCodes: [...MERGE_HOST_WARNINGS],
247
+ tooLarge: countMergeStatements(snapshot) > MERGE_BATCH_MAX_STATEMENTS,
248
+ };
249
+ }
250
+ export async function commitMergeBatch(db, snapshot, now) {
251
+ const { fromDid, intoDid } = snapshot;
252
+ const stmts = [];
253
+ for (const cred of snapshot.credentials) {
254
+ stmts.push(db.prepare("UPDATE cs_connected_accounts SET userDid = ?, updatedAt = ? WHERE did = ?").bind(intoDid, now, cred.did));
255
+ }
256
+ const movedPrimary = willMovePrimaryCredential(snapshot);
257
+ if (movedPrimary) {
258
+ stmts.push(db
259
+ .prepare("UPDATE cs_users SET primaryCredentialDid = NULL, updatedAt = ? WHERE did = ?")
260
+ .bind(now, fromDid));
261
+ }
262
+ for (const row of snapshot.memberships.moved) {
263
+ stmts.push(db
264
+ .prepare("UPDATE cs_memberships SET user_did = ?, updated_at = ? WHERE user_did = ? AND instance_did = ?")
265
+ .bind(intoDid, now, fromDid, row.instanceDid));
266
+ }
267
+ for (const row of snapshot.memberships.merged) {
268
+ stmts.push(db
269
+ .prepare("UPDATE cs_memberships SET role = ?, updated_at = ? WHERE user_did = ? AND instance_did = ?")
270
+ .bind(row.keptRole, now, intoDid, row.instanceDid));
271
+ stmts.push(db
272
+ .prepare("DELETE FROM cs_memberships WHERE user_did = ? AND instance_did = ?")
273
+ .bind(fromDid, row.instanceDid));
274
+ }
275
+ for (const key of snapshot.accessKeys) {
276
+ stmts.push(db
277
+ .prepare("UPDATE cs_access_keys SET createdBy = ?, updatedAt = ? WHERE accessKeyId = ?")
278
+ .bind(intoDid, now, key.accessKeyId));
279
+ }
280
+ stmts.push(db
281
+ .prepare(`INSERT INTO cs_did_aliases (did, canonicalDid, reason, evidence, createdAt)
282
+ VALUES (?, ?, 'merged', NULL, ?)
283
+ ON CONFLICT(did) DO UPDATE SET
284
+ canonicalDid = excluded.canonicalDid,
285
+ reason = excluded.reason`)
286
+ .bind(fromDid, intoDid, now));
287
+ stmts.push(db.prepare(FLATTEN_DID_ALIASES_SQL).bind(intoDid, fromDid));
288
+ stmts.push(db
289
+ .prepare("UPDATE cs_refresh_tokens SET revokedAt = datetime('now') WHERE userDid = ? AND revokedAt IS NULL")
290
+ .bind(fromDid));
291
+ stmts.push(db
292
+ .prepare("UPDATE cs_refresh_tokens SET revokedAt = datetime('now') WHERE userDid = ? AND revokedAt IS NULL")
293
+ .bind(intoDid));
294
+ const fromPasskey = Math.max(0, snapshot.fromPasskeyCount - snapshot.movedPasskeyCount);
295
+ const intoPasskey = snapshot.intoPasskeyCount + snapshot.movedPasskeyCount;
296
+ stmts.push(db
297
+ .prepare(`UPDATE cs_users SET mergedInto = ?, mergedAt = ?, mergeSnapshot = ?, passkeyCount = ?, updatedAt = ?
298
+ WHERE did = ?`)
299
+ .bind(intoDid, now, JSON.stringify(snapshot), fromPasskey, now, fromDid));
300
+ stmts.push(db.prepare("UPDATE cs_users SET passkeyCount = ?, updatedAt = ? WHERE did = ?").bind(intoPasskey, now, intoDid));
301
+ const expected = countMergeStatements(snapshot);
302
+ if (stmts.length !== expected) {
303
+ throw new Error(`Merge statement count mismatch: expected ${expected}, built ${stmts.length}`);
304
+ }
305
+ if (stmts.length > MERGE_BATCH_MAX_STATEMENTS) {
306
+ throw new Error(`${MERGE_TOO_LARGE_ERROR} (${stmts.length})`);
307
+ }
308
+ await db.batch(stmts);
309
+ }
310
+ export async function hashSnapshot(snapshot) {
311
+ return hashRefreshToken(JSON.stringify(snapshot));
312
+ }
313
+ //# sourceMappingURL=account-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-merge.js","sourceRoot":"","sources":["../../src/store/account-merge.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,44 @@
6
6
  */
7
7
  import type { BindHostResult } from "../blocklet-service-rpc-types.js";
8
8
  import type { AccessKeyInfo, AccessPolicyInfo, AuditLogInfo, CreateAccessKeyInput, CreateAccessPolicyInput, CreateAuditLogInput, CreateInvitationInput, CreateSecurityRuleInput, InvitationInfo, MemberInfo, SecurityRuleInfo, StoredAccessKey, StoredConnectedAccount, StoredInvitation, StoredUser, UpdateAccessKeyInput, UpdateAccessPolicyInput, UpdateSecurityRuleInput } from "../types.js";
9
+ import { type MergeIntentRow, type MergeSnapshot } from "./account-merge.js";
10
+ /** Allowed `cs_did_aliases.reason` values. Unknown reasons are rejected on write. */
11
+ export declare const DID_ALIAS_REASONS: readonly ["merged", "chain-migrated"];
12
+ export type DidAliasReason = (typeof DID_ALIAS_REASONS)[number];
13
+ export interface UpsertDidAliasInput {
14
+ did: string;
15
+ canonicalDid: string;
16
+ reason: DidAliasReason;
17
+ evidence?: string | null;
18
+ }
19
+ /**
20
+ * Identity lookup: user DID → connected-account DID → alias source.
21
+ *
22
+ * The user arm excludes alias sources so a retained merged `cs_users(A)`
23
+ * row cannot hide alias `A→B` (#149 / SD-147). The connected-account arm
24
+ * excludes alias-source `ca.did` so a leftover wallet row on a
25
+ * chain-migrated OLD DID cannot hide `OLD→NEW` (#169). Skipped merge
26
+ * credentials are not alias sources; `getUserByDidOrConnectedAccount`
27
+ * follows `mergedInto` so those rows resolve to the surviving account
28
+ * (#176). Do not reorder the arms.
29
+ */
30
+ export declare const GET_USER_BY_DID_OR_CONNECTED_ACCOUNT_SQL = "SELECT u.* FROM cs_users u\n WHERE u.did = ?\n AND NOT EXISTS (SELECT 1 FROM cs_did_aliases a WHERE a.did = u.did)\nUNION ALL\nSELECT u.* FROM cs_connected_accounts ca\n JOIN cs_users u ON ca.userDid = u.did\n WHERE ca.did = ?\n AND NOT EXISTS (SELECT 1 FROM cs_did_aliases a WHERE a.did = ca.did)\nUNION ALL\nSELECT u.* FROM cs_did_aliases a\n JOIN cs_users u ON a.canonicalDid = u.did WHERE a.did = ?\nLIMIT 1";
31
+ /** Flatten ancestors when a canonical DID itself becomes an alias (one hop). */
32
+ export declare const FLATTEN_DID_ALIASES_SQL = "UPDATE cs_did_aliases SET canonicalDid = ? WHERE canonicalDid = ?";
33
+ /**
34
+ * Backfill `cs_users.primaryCredentialDid` from `sourceProvider`.
35
+ * Among matching connected-account rows, prefer `account.did === user.did`,
36
+ * else oldest `createdAt` (then `did` for a stable tie-break). Leave NULL
37
+ * when no row matches. Idempotent: already-set values are left alone.
38
+ */
39
+ export declare const BACKFILL_PRIMARY_CREDENTIAL_SQL = "UPDATE cs_users\nSET primaryCredentialDid = picked.credDid\nFROM (\n SELECT ownerDid, credDid FROM (\n SELECT\n u.did AS ownerDid,\n ca.did AS credDid,\n ROW_NUMBER() OVER (\n PARTITION BY u.did\n ORDER BY\n CASE WHEN ca.did = u.did THEN 0 ELSE 1 END,\n ca.createdAt ASC,\n ca.did ASC\n ) AS rn\n FROM cs_users u\n JOIN cs_connected_accounts ca\n ON ca.userDid = u.did AND ca.provider = u.sourceProvider\n ) ranked\n WHERE rn = 1\n) picked\nWHERE cs_users.did = picked.ownerDid\n AND cs_users.primaryCredentialDid IS NULL";
40
+ /**
41
+ * Drop extra `(provider, id)` rows so UNIQUE(provider, id) can be created
42
+ * on a legacy database. Keep `did = userDid`, else the oldest `createdAt`
43
+ * (then `did`). `id IS NULL` rows are left alone — SQLite UNIQUE treats
44
+ * NULL as distinct.
45
+ */
46
+ export declare const DEDUPE_CONNECTED_ACCOUNTS_SQL = "DELETE FROM cs_connected_accounts\nWHERE id IS NOT NULL\n AND rowid IN (\n SELECT rowid FROM (\n SELECT\n rowid,\n ROW_NUMBER() OVER (\n PARTITION BY provider, id\n ORDER BY\n CASE WHEN did = userDid THEN 0 ELSE 1 END,\n COALESCE(createdAt, '') ASC,\n did ASC\n ) AS rn\n FROM cs_connected_accounts\n WHERE id IS NOT NULL\n ) ranked\n WHERE rn > 1\n )";
9
47
  /** Session-JWT and OAuth refresh TTL. W4 aligns OAuth to this; do not invent a second constant. */
10
48
  export declare const REFRESH_TOKEN_TTL_SECONDS: number;
11
49
  export interface IssuedRefreshToken {
@@ -87,7 +125,7 @@ export declare class D1Store {
87
125
  assumeMigrated?: boolean;
88
126
  });
89
127
  /** Run schema migration. Idempotent — only executes once per isolate.
90
- * Optimized: merges CREATE TABLE/INDEX into batches, ALTER TABLE in parallel. */
128
+ * Optimized: CREATE TABLE in a batch, ALTER TABLE in parallel, then indexes. */
91
129
  migrate(): Promise<void>;
92
130
  /** @internal Backwards-compatible alias for migrate(). */
93
131
  ensureSchema(): Promise<void>;
@@ -119,6 +157,12 @@ export declare class D1Store {
119
157
  }): Promise<void>;
120
158
  getUserByDid(did: string): Promise<StoredUser | null>;
121
159
  getUserByEmail(email: string): Promise<StoredUser | null>;
160
+ /**
161
+ * True iff another unmerged user shares `selfDid`'s verified email.
162
+ * Uses `lower(trim(email))` — do not call `getUserByEmail` (exact match,
163
+ * may return self). Users are global; no instanceDid filter. `SELECT 1 LIMIT 1`.
164
+ */
165
+ hasVerifiedEmailMergeCandidate(selfDid: string): Promise<boolean>;
122
166
  updateLastLogin(did: string, ip?: string, domain?: string): Promise<void>;
123
167
  incrementPasskeyCount(did: string): Promise<void>;
124
168
  getUserCount(): Promise<number>;
@@ -222,23 +266,41 @@ export declare class D1Store {
222
266
  userInfo?: string;
223
267
  }, actor: string): Promise<void>;
224
268
  /**
225
- * Update a user's `sourceProvider` (the provider they registered with).
269
+ * Update a user's `sourceProvider` (display-only registration label).
226
270
  *
227
- * Must stay in step with `relabelConnectedAccountProvider`: `handleUnbind`
228
- * reads `sourceProvider` to refuse removing the registration account, so a
229
- * relabel that left this field pointing at a provider the user no longer has
230
- * a row for would silently disarm that guard.
271
+ * Security guards read `primaryCredentialDid`, not this field. Relabel is
272
+ * kept so profile `isMain` / audit display stay in step with the bound
273
+ * provider; it must not arm or disarm unbind / last-passkey checks.
231
274
  */
232
275
  updateUserSourceProvider(did: string, sourceProvider: string, actor: string): Promise<void>;
233
- getConnectedAccountById(credentialId: string): Promise<StoredConnectedAccount | null>;
276
+ getConnectedAccountById(id: string, provider: string): Promise<StoredConnectedAccount | null>;
234
277
  getConnectedAccountByDid(did: string): Promise<StoredConnectedAccount | null>;
235
278
  updateCounter(did: string, counter: number): Promise<void>;
236
279
  getConnectedAccountsByUserDid(userDid: string): Promise<StoredConnectedAccount[]>;
237
280
  getConnectedAccountByProviderAndUser(provider: string, userDid: string): Promise<StoredConnectedAccount | null>;
238
281
  getConnectedAccountsByProviderAndUser(provider: string, userDid: string): Promise<StoredConnectedAccount[]>;
239
282
  getUserByDidOrConnectedAccount(did: string): Promise<StoredUser | null>;
283
+ /**
284
+ * Insert or update a one-hop DID alias. When `canonicalDid` is itself an
285
+ * alias, the write lands on that row's canonical. When `did` becomes an
286
+ * alias, every row pointing at it is rewritten in the same `db.batch`.
287
+ */
288
+ upsertDidAlias(input: UpsertDidAliasInput): Promise<void>;
289
+ upsertDidAliases(inputs: UpsertDidAliasInput[]): Promise<void>;
240
290
  decrementPasskeyCount(did: string): Promise<void>;
241
291
  updateConnectedAccountName(did: string, name: string, actor: string): Promise<void>;
292
+ /**
293
+ * Point `primaryCredentialDid` at a credential the user owns, or NULL.
294
+ * Rejects a pointer at another user's row so writers cannot cross tenants.
295
+ */
296
+ setPrimaryCredentialDid(userDid: string, credentialDid: string | null, actor?: string): Promise<void>;
297
+ /** Fill primary only when it is still NULL. Used after first credential insert. */
298
+ private maybeFillPrimaryCredentialDid;
299
+ /**
300
+ * Next primary among remaining credentials of the same user.
301
+ * Prefer `account.did === user.did`, else oldest `createdAt` (then `did`).
302
+ */
303
+ private pickReplacementPrimaryDid;
242
304
  deleteConnectedAccount(did: string): Promise<void>;
243
305
  createAccessKey(input: CreateAccessKeyInput): Promise<StoredAccessKey>;
244
306
  getAccessKeyById(accessKeyId: string): Promise<AccessKeyInfo | null>;
@@ -496,6 +558,12 @@ export declare class D1Store {
496
558
  rotateRefreshToken(oldPlaintext: string, rotationSecret: string): Promise<IssuedRefreshToken>;
497
559
  /** Revoke every token in a rotation family (theft containment). */
498
560
  revokeRefreshTokenFamily(familyId: string): Promise<void>;
561
+ /**
562
+ * Revoke every refresh family for a user (unbind / delete stop-loss).
563
+ * `cs_refresh_tokens` has no credential column — this is user-scoped, not
564
+ * per-provider. Uses `idx_refresh_tokens_userDid`. Does not touch access JWTs.
565
+ */
566
+ revokeRefreshTokensForUser(userDid: string): Promise<void>;
499
567
  /**
500
568
  * Look up a refresh token by plaintext. Used by the OAuth refresh grant.
501
569
  * Session-JWT rows have accessKeyId = NULL — callers must reject those.
@@ -526,6 +594,28 @@ export declare class D1Store {
526
594
  expiresAt: string;
527
595
  };
528
596
  }): Promise<void>;
597
+ createMergeStart(intoDid: string): Promise<{
598
+ challenge: string;
599
+ expiresAt: string;
600
+ }>;
601
+ getMergeStart(challenge: string): Promise<{
602
+ intoDid: string;
603
+ } | null>;
604
+ deleteMergeStart(challenge: string): Promise<void>;
605
+ createMergeIntent(fromDid: string, intoDid: string): Promise<{
606
+ token: string;
607
+ expiresAt: string;
608
+ }>;
609
+ getMergeIntent(tokenHash: string): Promise<MergeIntentRow | null>;
610
+ planAccountMerge(fromDid: string, intoDid: string): Promise<MergeSnapshot>;
611
+ commitAccountMerge(tokenHash: string, actorDid: string): Promise<{
612
+ ok: true;
613
+ snapshot: MergeSnapshot;
614
+ } | {
615
+ ok: false;
616
+ error: string;
617
+ status: number;
618
+ }>;
529
619
  }
530
620
  export {};
531
621
  //# sourceMappingURL=d1-store.d.ts.map