@arcblock/did-connect-service 4.1.22 → 4.1.24
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/_generated/asset-bytes.js +1 -1
- package/dist/_generated/asset-manifest.js +4 -4
- package/dist/_generated/login-bundle-string.d.ts +1 -1
- package/dist/_generated/login-bundle-string.d.ts.map +1 -1
- package/dist/_generated/login-bundle-string.js +1 -1
- package/dist/_generated/login-bundle-string.js.map +1 -1
- package/dist/assets/admin-core.16704b2e.js +2065 -0
- package/dist/assets/admin-core.1fc3260c.js +1623 -0
- package/dist/assets/admin-core.5a2d69b0.js +2067 -0
- package/dist/assets/admin-core.9fff6042.js +2083 -0
- package/dist/assets/admin-core.a13c2729.js +1461 -0
- package/dist/assets/{admin-core.40671087.js → admin-core.a63bbc69.js} +2 -12
- package/dist/assets/admin-core.c0b5af61.js +1393 -0
- package/dist/assets/admin-core.cbbdbe6d.js +1465 -0
- package/dist/assets/admin-core.e83fd379.js +1397 -0
- package/dist/assets/admin-extra.143b5774.js +2543 -0
- package/dist/assets/admin-extra.35b91f98.js +2543 -0
- package/dist/assets/admin-extra.531b187f.js +2552 -0
- package/dist/assets/admin-extra.7ca9c16b.js +2529 -0
- package/dist/assets/admin-extra.841b2bbe.js +2530 -0
- package/dist/assets/admin-extra.afcb3651.js +2528 -0
- package/dist/assets/admin.7c5d5f04.css +2312 -0
- package/dist/assets/admin.c26bb17a.css +2219 -0
- package/dist/assets/login.0bf3d739.js +720 -0
- package/dist/assets/login.4404e695.js +720 -0
- package/dist/assets/login.bb9f8b03.js +720 -0
- package/dist/assets/login.d3f05790.js +720 -0
- package/dist/assets/login.fa25f37a.js +720 -0
- package/dist/assets/login.fb0bf7b4.js +720 -0
- package/dist/blocklet-service-rpc.d.ts.map +1 -1
- package/dist/blocklet-service-rpc.js +11 -8
- package/dist/blocklet-service-rpc.js.map +1 -1
- package/dist/blocklet-service.d.ts +11 -8
- package/dist/blocklet-service.d.ts.map +1 -1
- package/dist/blocklet-service.js +32 -38
- package/dist/blocklet-service.js.map +1 -1
- package/dist/embedded.d.ts +42 -1
- package/dist/embedded.d.ts.map +1 -1
- package/dist/embedded.js +60 -1
- package/dist/embedded.js.map +1 -1
- package/dist/handlers/access-key-connect-handler.d.ts.map +1 -1
- package/dist/handlers/access-key-connect-handler.js +12 -1
- package/dist/handlers/access-key-connect-handler.js.map +1 -1
- package/dist/handlers/account-merge-handler.d.ts +63 -0
- package/dist/handlers/account-merge-handler.d.ts.map +1 -0
- package/dist/handlers/account-merge-handler.js +263 -0
- package/dist/handlers/account-merge-handler.js.map +1 -0
- package/dist/handlers/auth-handler.d.ts +12 -5
- package/dist/handlers/auth-handler.d.ts.map +1 -1
- package/dist/handlers/auth-handler.js +54 -8
- package/dist/handlers/auth-handler.js.map +1 -1
- package/dist/handlers/blocklet-js-handler.d.ts +3 -2
- package/dist/handlers/blocklet-js-handler.d.ts.map +1 -1
- package/dist/handlers/blocklet-js-handler.js +4 -2
- package/dist/handlers/blocklet-js-handler.js.map +1 -1
- package/dist/handlers/branding-handler.d.ts +4 -0
- package/dist/handlers/branding-handler.d.ts.map +1 -1
- package/dist/handlers/branding-handler.js +12 -6
- package/dist/handlers/branding-handler.js.map +1 -1
- package/dist/handlers/did-connect-handler.d.ts +22 -0
- package/dist/handlers/did-connect-handler.d.ts.map +1 -1
- package/dist/handlers/did-connect-handler.js +191 -17
- package/dist/handlers/did-connect-handler.js.map +1 -1
- package/dist/handlers/email-login-handler.d.ts +2 -0
- package/dist/handlers/email-login-handler.d.ts.map +1 -1
- package/dist/handlers/email-login-handler.js +30 -14
- package/dist/handlers/email-login-handler.js.map +1 -1
- package/dist/handlers/oauth-handler.d.ts +15 -0
- package/dist/handlers/oauth-handler.d.ts.map +1 -1
- package/dist/handlers/oauth-handler.js +107 -43
- package/dist/handlers/oauth-handler.js.map +1 -1
- package/dist/handlers/passkey-handler.d.ts.map +1 -1
- package/dist/handlers/passkey-handler.js +40 -8
- package/dist/handlers/passkey-handler.js.map +1 -1
- package/dist/handlers/team-handler.d.ts +1 -1
- package/dist/handlers/team-handler.d.ts.map +1 -1
- package/dist/handlers/team-handler.js +43 -3
- package/dist/handlers/team-handler.js.map +1 -1
- package/dist/handlers/ticket-handler.d.ts.map +1 -1
- package/dist/handlers/ticket-handler.js +4 -2
- package/dist/handlers/ticket-handler.js.map +1 -1
- package/dist/handlers/unbind-account.d.ts +22 -0
- package/dist/handlers/unbind-account.d.ts.map +1 -0
- package/dist/handlers/unbind-account.js +20 -0
- package/dist/handlers/unbind-account.js.map +1 -0
- package/dist/http/security-headers.d.ts +38 -0
- package/dist/http/security-headers.d.ts.map +1 -0
- package/dist/http/security-headers.js +67 -0
- package/dist/http/security-headers.js.map +1 -0
- package/dist/identity/account-state.d.ts +37 -0
- package/dist/identity/account-state.d.ts.map +1 -0
- package/dist/identity/account-state.js +97 -0
- package/dist/identity/account-state.js.map +1 -0
- package/dist/identity/json-content-type.d.ts +14 -0
- package/dist/identity/json-content-type.d.ts.map +1 -0
- package/dist/identity/json-content-type.js +26 -0
- package/dist/identity/json-content-type.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/oauth-adapters/apple.d.ts +1 -1
- package/dist/oauth-adapters/apple.d.ts.map +1 -1
- package/dist/oauth-adapters/apple.js +2 -0
- package/dist/oauth-adapters/apple.js.map +1 -1
- package/dist/oauth-adapters/auth0-legacy.d.ts +1 -1
- package/dist/oauth-adapters/auth0-legacy.d.ts.map +1 -1
- package/dist/oauth-adapters/auth0-legacy.js +2 -0
- package/dist/oauth-adapters/auth0-legacy.js.map +1 -1
- package/dist/oauth-adapters/auth0.d.ts +1 -1
- package/dist/oauth-adapters/auth0.d.ts.map +1 -1
- package/dist/oauth-adapters/auth0.js +2 -0
- package/dist/oauth-adapters/auth0.js.map +1 -1
- package/dist/oauth-adapters/github.d.ts.map +1 -1
- package/dist/oauth-adapters/github.js +19 -12
- package/dist/oauth-adapters/github.js.map +1 -1
- package/dist/oauth-adapters/google.d.ts +1 -1
- package/dist/oauth-adapters/google.d.ts.map +1 -1
- package/dist/oauth-adapters/google.js +2 -0
- package/dist/oauth-adapters/google.js.map +1 -1
- package/dist/oauth-adapters/types.d.ts +7 -0
- package/dist/oauth-adapters/types.d.ts.map +1 -1
- package/dist/oauth-adapters/types.js +4 -1
- package/dist/oauth-adapters/types.js.map +1 -1
- package/dist/package-branding.d.ts +18 -0
- package/dist/package-branding.d.ts.map +1 -0
- package/dist/package-branding.js +103 -0
- package/dist/package-branding.js.map +1 -0
- package/dist/pages/admin/i18n.d.ts.map +1 -1
- package/dist/pages/admin/i18n.js +86 -0
- package/dist/pages/admin/i18n.js.map +1 -1
- package/dist/pages/admin/index.d.ts +4 -0
- package/dist/pages/admin/index.d.ts.map +1 -1
- package/dist/pages/admin/index.js +10 -2
- package/dist/pages/admin/index.js.map +1 -1
- package/dist/pages/admin/merge-confirm-view.d.ts +48 -0
- package/dist/pages/admin/merge-confirm-view.d.ts.map +1 -0
- package/dist/pages/admin/merge-confirm-view.js +85 -0
- package/dist/pages/admin/merge-confirm-view.js.map +1 -0
- package/dist/pages/admin/merge-method-picker.d.ts +12 -0
- package/dist/pages/admin/merge-method-picker.d.ts.map +1 -0
- package/dist/pages/admin/merge-method-picker.js +34 -0
- package/dist/pages/admin/merge-method-picker.js.map +1 -0
- package/dist/pages/admin/oauth-popup-close.d.ts +13 -0
- package/dist/pages/admin/oauth-popup-close.d.ts.map +1 -0
- package/dist/pages/admin/oauth-popup-close.js +15 -0
- package/dist/pages/admin/oauth-popup-close.js.map +1 -0
- package/dist/pages/admin/styles.d.ts +1 -1
- package/dist/pages/admin/styles.d.ts.map +1 -1
- package/dist/pages/admin/styles.js +83 -0
- package/dist/pages/admin/styles.js.map +1 -1
- package/dist/pages/admin/tab-audit.d.ts +1 -1
- package/dist/pages/admin/tab-audit.d.ts.map +1 -1
- package/dist/pages/admin/tab-audit.js +12 -0
- package/dist/pages/admin/tab-audit.js.map +1 -1
- package/dist/pages/admin/tab-profile-accounts.d.ts.map +1 -1
- package/dist/pages/admin/tab-profile-accounts.js +492 -3
- package/dist/pages/admin/tab-profile-accounts.js.map +1 -1
- package/dist/pages/invite-page.d.ts +1 -0
- package/dist/pages/invite-page.d.ts.map +1 -1
- package/dist/pages/invite-page.js +13 -3
- package/dist/pages/invite-page.js.map +1 -1
- package/dist/store/account-merge.d.ts +167 -0
- package/dist/store/account-merge.d.ts.map +1 -0
- package/dist/store/account-merge.js +313 -0
- package/dist/store/account-merge.js.map +1 -0
- package/dist/store/d1-store.d.ts +104 -7
- package/dist/store/d1-store.d.ts.map +1 -1
- package/dist/store/d1-store.js +449 -23
- package/dist/store/d1-store.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/migrations/0015_connected_accounts_id_index.sql +6 -0
- package/migrations/0016_did_aliases.sql +11 -0
- package/migrations/0017_unbind_revoke_and_cascade.sql +49 -0
- package/migrations/0018_primary_credential_did.sql +54 -0
- package/migrations/0019_account_merge.sql +16 -0
- package/migrations/0020_dedupe_connected_accounts.sql +24 -0
- 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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"}
|