@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-key-connect-handler.js","sourceRoot":"","sources":["../../src/handlers/access-key-connect-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAgC,MAAM,iCAAiC,CAAC;AAI1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"access-key-connect-handler.js","sourceRoot":"","sources":["../../src/handlers/access-key-connect-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAgC,MAAM,iCAAiC,CAAC;AAI1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAElD,kFAAkF;AAClF,SAAS,cAAc,CAAmB,KAAQ;IAChD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAe,CAAC;AACpG,CAAC;AAcD,MAAM,OAAO,uBAAuB;IAC1B,KAAK,CAAU;IACf,IAAI,CAAO;IACX,gBAAgB,CAAmB;IACnC,WAAW,CAA2B;IACtC,kBAAkB,CAA8D;IAChF,MAAM,CAAS;IAEvB,YAAY,OAAgC;QAC1C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,WAAoB;QAChD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAEzB,6BAA6B;QAC7B,IACE,QAAQ,KAAK,qCAAqC;YAClD,OAAO,CAAC,MAAM,KAAK,KAAK,EACxB,CAAC;YACD,sEAAsE;YACtE,0EAA0E;YAC1E,6EAA6E;YAC7E,sEAAsE;YACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB;gBACtC,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC;gBAC5C,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,WAAW,GAAwC,QAAQ;gBAC/D,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,EAAE;gBACtD,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YACrB,mEAAmE;YACnE,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;YACpD,OAAO,IAAI,QAAQ,CACjB,yBAAyB,CACvB,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,WAAW,EACjE,YAAY,CAAC,OAAO,CAAC,CACtB,EACD;gBACE,OAAO,EAAE;oBACP,cAAc,EAAE,0BAA0B;oBAC1C,eAAe,EAAE,UAAU;iBAC5B;aACF,CACF,CAAC;QACJ,CAAC;QAED,cAAc;QACd,IAAI,QAAQ,KAAK,6CAA6C,EAAE,CAAC;YAC/D,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAClE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;gBAAE,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC9D,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,qBAAqB;QACrB,IACE,QAAQ,KAAK,+CAA+C;YAC5D,OAAO,CAAC,MAAM,KAAK,MAAM,EACzB,CAAC;YACD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,mBAAmB,CAAC,GAAQ;QACxC,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QACvD,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IACtD,CAAC;IAED,8EAA8E;IACtE,KAAK,CAAC,aAAa,CAAC,QAAiB;QAC3C,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;YAC5D,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QAED,uEAAuE;QACvE,mEAAmE;QACnE,IAAI,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACrC,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;aACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;aAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;QAEtE,4CAA4C;QAC5C,MAAM,IAAI,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC;QACjD,MAAM,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAE9E,OAAO,YAAY,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,qEAAqE;IAC7D,KAAK,CAAC,UAAU,CAAC,OAAgB;QACvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG;YAAE,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;QAE7D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;QAED,0CAA0C;QAC1C,OAAO,YAAY,CAAC;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI;YAC1C,eAAe,EAAE,OAAO,CAAC,2BAA2B,IAAI,IAAI;SAC7D,CAAC,CAAC;IACL,CAAC;IAED,oDAAoD;IAC5C,KAAK,CAAC,aAAa,CAAC,OAAgB;QAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzD,IAAI,GAAG;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QACtD,OAAO,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,8EAA8E;IACtE,KAAK,CAAC,SAAS,CAAC,OAAgB,EAAE,WAAoB;QAC5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,IAAsD,CAAC;QAC3D,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAqD,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;QAED,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,UAAU,GAAI,MAAM,CAAC,IAAa,IAAI,OAAO,CAAC;QACpD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3F,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;YAChC,OAAO,YAAY,CACjB,EAAE,KAAK,EAAE,iBAAiB,MAAM,CAAC,aAAa,CAAC,qBAAqB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAC9F,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,gDAAgD;gBACzD,GAAG,EAAE,YAAY;gBACjB,aAAa;gBACb,UAAU;aACX,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG;YAAE,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;QAE7D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5G,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,iDAAiD,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;YACzG,OAAO,YAAY,CACjB,EAAE,KAAK,EAAE,0CAA0C,EAAE,EACrD,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,6CAA6C,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7H,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;QAED,0EAA0E;QAC1E,iEAAiE;QACjE,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,mEAAmE;gBAC5E,GAAG,EAAE,YAAY;gBACjB,GAAG;aACJ,CAAC,CAAC;YACH,OAAO,YAAY,CACjB,EAAE,KAAK,EAAE,6FAA6F,EAAE,EACxG,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,iFAAiF;QACjF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC;YAC9D,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,eAAe,OAAO,CAAC,MAAM,IAAI,UAAU,EAAE;YACrD,SAAS,EAAE,MAAM,CAAC,GAAG;YACrB,QAAQ,EAAE,QAAQ;YAClB,WAAW;SACZ,CAAC,CAAC;QAEH,iDAAiD;QACjD,MAAM,SAAS,GAAG,MAAM,UAAU,CAChC,SAAS,CAAC,eAAe,EACzB,OAAO,CAAC,SAAS,CAClB,CAAC;QAEF,MAAM,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,GAAG,EAAE;YAC3C,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,wBAAwB,EAAE,SAAS;SACpC,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;IACxE,CAAC;CACF;AAED,SAAS,YAAY,CAAC,IAAa,EAAE,MAAM,GAAG,GAAG;IAC/C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM;QACN,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,eAAe,EAAE,mBAAmB;SACrC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual-auth account merge (#149 / SD-149 / SD-149c).
|
|
3
|
+
*
|
|
4
|
+
* Routes (under /.well-known/service/api/account/merge):
|
|
5
|
+
* GET /candidate — session-only boolean: another unmerged user shares
|
|
6
|
+
* this verified email. Query/body did/email are ignored.
|
|
7
|
+
* POST /start — B starts; returns a challenge bound to intoDid=B
|
|
8
|
+
* POST /dry-run — same plan as commit, no writes
|
|
9
|
+
* POST /commit — consume intent + atomic merge
|
|
10
|
+
* Unknown actions (including former /rollback) return explicit 404 JSON.
|
|
11
|
+
* GET /candidate is handled before the POST-only guard (#192).
|
|
12
|
+
*
|
|
13
|
+
* Prove-A uses the dedicated `merge-proof` DID Connect action (wallet
|
|
14
|
+
* description is not a login). See `completeMergeProof`.
|
|
15
|
+
*/
|
|
16
|
+
import { type Logger } from "../logger.js";
|
|
17
|
+
import type { D1Store } from "../store/d1-store.js";
|
|
18
|
+
export declare const MERGE_CHALLENGE_COOKIE = "connect_merge_challenge";
|
|
19
|
+
export declare const MERGE_ROUTE_PREFIX = "/.well-known/service/api/account/merge";
|
|
20
|
+
/** WalletHandlers action for prove-A. handleComplete mints only when the session has this action. */
|
|
21
|
+
export declare const MERGE_PROOF_ACTION = "merge-proof";
|
|
22
|
+
/** Shown on the wallet confirm screen for the merge-proof action (#170). */
|
|
23
|
+
export declare const MERGE_PROOF_WALLET_DESCRIPTION = "Confirm merging this account into another account. This is not a login.";
|
|
24
|
+
export interface AccountMergeHandlerOptions {
|
|
25
|
+
store: D1Store;
|
|
26
|
+
jwtSecret: string;
|
|
27
|
+
cookieName: string;
|
|
28
|
+
logger?: Logger;
|
|
29
|
+
appDid?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Body only — query/cookie made the challenge injectable (#170). */
|
|
32
|
+
export declare function extractMergeChallenge(_request: Request, body?: {
|
|
33
|
+
mergeChallenge?: unknown;
|
|
34
|
+
}): string | undefined;
|
|
35
|
+
export declare function completeMergeProof(opts: {
|
|
36
|
+
store: D1Store;
|
|
37
|
+
mergeChallenge: string | null | undefined;
|
|
38
|
+
fromDid: string;
|
|
39
|
+
appDid?: string | null;
|
|
40
|
+
ip?: string;
|
|
41
|
+
instanceDid?: string;
|
|
42
|
+
}): Promise<Response | null>;
|
|
43
|
+
export declare class AccountMergeHandler {
|
|
44
|
+
private readonly store;
|
|
45
|
+
private readonly jwtSecret;
|
|
46
|
+
private readonly cookieName;
|
|
47
|
+
private readonly logger;
|
|
48
|
+
private readonly appDid?;
|
|
49
|
+
constructor(options: AccountMergeHandlerOptions);
|
|
50
|
+
fetch(request: Request, instanceDid?: string): Promise<Response | null>;
|
|
51
|
+
private verifyCaller;
|
|
52
|
+
/**
|
|
53
|
+
* Boolean-only existence signal. `self` is the session DID — query/body
|
|
54
|
+
* `did`/`email` are not read (existence oracle). Users are global; this
|
|
55
|
+
* does not take instanceDid.
|
|
56
|
+
*/
|
|
57
|
+
private handleCandidate;
|
|
58
|
+
private handleStart;
|
|
59
|
+
private loadUsableIntent;
|
|
60
|
+
private handleDryRun;
|
|
61
|
+
private handleCommit;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=account-merge-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-merge-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/account-merge-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAY1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAChE,eAAO,MAAM,kBAAkB,2CAA2C,CAAC;AAC3E,qGAAqG;AACrG,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAChD,4EAA4E;AAC5E,eAAO,MAAM,8BAA8B,4EACgC,CAAC;AAE5E,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiBD,qEAAqE;AACrE,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EACjB,IAAI,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC,MAAM,GAAG,SAAS,CAKpB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqD3B;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;gBAErB,OAAO,EAAE,0BAA0B;IAQzC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;YAoD/D,YAAY;IAS1B;;;;OAIG;YACW,eAAe;YAKf,WAAW;YAiCX,gBAAgB;YAkBhB,YAAY;YAwBZ,YAAY;CA+B3B"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual-auth account merge (#149 / SD-149 / SD-149c).
|
|
3
|
+
*
|
|
4
|
+
* Routes (under /.well-known/service/api/account/merge):
|
|
5
|
+
* GET /candidate — session-only boolean: another unmerged user shares
|
|
6
|
+
* this verified email. Query/body did/email are ignored.
|
|
7
|
+
* POST /start — B starts; returns a challenge bound to intoDid=B
|
|
8
|
+
* POST /dry-run — same plan as commit, no writes
|
|
9
|
+
* POST /commit — consume intent + atomic merge
|
|
10
|
+
* Unknown actions (including former /rollback) return explicit 404 JSON.
|
|
11
|
+
* GET /candidate is handled before the POST-only guard (#192).
|
|
12
|
+
*
|
|
13
|
+
* Prove-A uses the dedicated `merge-proof` DID Connect action (wallet
|
|
14
|
+
* description is not a login). See `completeMergeProof`.
|
|
15
|
+
*/
|
|
16
|
+
import { requireJsonContentType } from "../identity/json-content-type.js";
|
|
17
|
+
import { verifyJWT } from "../identity/jwt.js";
|
|
18
|
+
import { consoleLogger } from "../logger.js";
|
|
19
|
+
import { didSpacePointer, hashMergeToken, hashSnapshot, intentIsUsable, MERGE_START_TTL_SECONDS, toMergeConfirmPlan, toMergePlanView, } from "../store/account-merge.js";
|
|
20
|
+
export const MERGE_CHALLENGE_COOKIE = "connect_merge_challenge";
|
|
21
|
+
export const MERGE_ROUTE_PREFIX = "/.well-known/service/api/account/merge";
|
|
22
|
+
/** WalletHandlers action for prove-A. handleComplete mints only when the session has this action. */
|
|
23
|
+
export const MERGE_PROOF_ACTION = "merge-proof";
|
|
24
|
+
/** Shown on the wallet confirm screen for the merge-proof action (#170). */
|
|
25
|
+
export const MERGE_PROOF_WALLET_DESCRIPTION = "Confirm merging this account into another account. This is not a login.";
|
|
26
|
+
function jsonResponse(data, status = 200, headers) {
|
|
27
|
+
return new Response(JSON.stringify(data), {
|
|
28
|
+
status,
|
|
29
|
+
headers: {
|
|
30
|
+
"Content-Type": "application/json",
|
|
31
|
+
"Cache-Control": "private, no-store",
|
|
32
|
+
...headers,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function jsonError(error, status) {
|
|
37
|
+
return jsonResponse({ error }, status);
|
|
38
|
+
}
|
|
39
|
+
/** Body only — query/cookie made the challenge injectable (#170). */
|
|
40
|
+
export function extractMergeChallenge(_request, body) {
|
|
41
|
+
if (typeof body?.mergeChallenge === "string" && body.mergeChallenge.trim()) {
|
|
42
|
+
return body.mergeChallenge.trim();
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
export async function completeMergeProof(opts) {
|
|
47
|
+
const challenge = typeof opts.mergeChallenge === "string" ? opts.mergeChallenge.trim() : "";
|
|
48
|
+
if (!challenge)
|
|
49
|
+
return null;
|
|
50
|
+
if (opts.appDid && opts.fromDid === opts.appDid) {
|
|
51
|
+
return jsonError("APP_SK is not evidence of account control", 403);
|
|
52
|
+
}
|
|
53
|
+
const start = await opts.store.getMergeStart(challenge);
|
|
54
|
+
if (!start) {
|
|
55
|
+
return jsonError("Invalid or expired merge challenge", 400);
|
|
56
|
+
}
|
|
57
|
+
if (opts.fromDid === start.intoDid) {
|
|
58
|
+
return jsonError("Cannot merge an account into itself", 400);
|
|
59
|
+
}
|
|
60
|
+
const fromUser = await opts.store.getUserByDid(opts.fromDid);
|
|
61
|
+
if (!fromUser) {
|
|
62
|
+
return jsonError("Source account not found", 400);
|
|
63
|
+
}
|
|
64
|
+
if (fromUser.mergedInto) {
|
|
65
|
+
return jsonError("Source account has already been merged", 403);
|
|
66
|
+
}
|
|
67
|
+
const intoUser = await opts.store.getUserByDid(start.intoDid);
|
|
68
|
+
if (!intoUser) {
|
|
69
|
+
return jsonError("Target account not found", 400);
|
|
70
|
+
}
|
|
71
|
+
if (intoUser.mergedInto) {
|
|
72
|
+
return jsonError("Target account has already been merged", 403);
|
|
73
|
+
}
|
|
74
|
+
const issued = await opts.store.createMergeIntent(opts.fromDid, start.intoDid);
|
|
75
|
+
await opts.store.deleteMergeStart(challenge);
|
|
76
|
+
await opts.store.createAuditLog({
|
|
77
|
+
action: "account.merge.proof",
|
|
78
|
+
operatorDid: opts.fromDid,
|
|
79
|
+
targetDid: start.intoDid,
|
|
80
|
+
metadata: { fromDid: opts.fromDid, intoDid: start.intoDid },
|
|
81
|
+
ip: opts.ip,
|
|
82
|
+
instanceDid: opts.instanceDid && opts.instanceDid !== "_global_" ? opts.instanceDid : undefined,
|
|
83
|
+
});
|
|
84
|
+
return jsonResponse({
|
|
85
|
+
ok: true,
|
|
86
|
+
mergeIntent: issued.token,
|
|
87
|
+
fromDid: opts.fromDid,
|
|
88
|
+
intoDid: start.intoDid,
|
|
89
|
+
expiresAt: issued.expiresAt,
|
|
90
|
+
didSpace: { copied: false, pointer: didSpacePointer(opts.fromDid) },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export class AccountMergeHandler {
|
|
94
|
+
store;
|
|
95
|
+
jwtSecret;
|
|
96
|
+
cookieName;
|
|
97
|
+
logger;
|
|
98
|
+
appDid;
|
|
99
|
+
constructor(options) {
|
|
100
|
+
this.store = options.store;
|
|
101
|
+
this.jwtSecret = options.jwtSecret;
|
|
102
|
+
this.cookieName = options.cookieName;
|
|
103
|
+
this.logger = options.logger ?? consoleLogger;
|
|
104
|
+
this.appDid = options.appDid;
|
|
105
|
+
}
|
|
106
|
+
async fetch(request, instanceDid) {
|
|
107
|
+
const url = new URL(request.url);
|
|
108
|
+
if (!url.pathname.startsWith(`${MERGE_ROUTE_PREFIX}/`))
|
|
109
|
+
return null;
|
|
110
|
+
const action = url.pathname.slice(MERGE_ROUTE_PREFIX.length + 1);
|
|
111
|
+
// GET /candidate must run before the POST-only guard. A `case "candidate"`
|
|
112
|
+
// inside the POST switch would 405 forever (#192).
|
|
113
|
+
if (action === "candidate") {
|
|
114
|
+
if (request.method !== "GET") {
|
|
115
|
+
return jsonError("Method not allowed", 405);
|
|
116
|
+
}
|
|
117
|
+
const caller = await this.verifyCaller(request);
|
|
118
|
+
if (!caller)
|
|
119
|
+
return jsonError("Authentication required", 401);
|
|
120
|
+
return this.handleCandidate(caller.did);
|
|
121
|
+
}
|
|
122
|
+
if (request.method !== "POST") {
|
|
123
|
+
return jsonError("Method not allowed", 405);
|
|
124
|
+
}
|
|
125
|
+
const rejected = requireJsonContentType(request);
|
|
126
|
+
if (rejected)
|
|
127
|
+
return rejected;
|
|
128
|
+
const caller = await this.verifyCaller(request);
|
|
129
|
+
if (!caller)
|
|
130
|
+
return jsonError("Authentication required", 401);
|
|
131
|
+
let body;
|
|
132
|
+
try {
|
|
133
|
+
const raw = await request.text();
|
|
134
|
+
if (!raw.trim())
|
|
135
|
+
return jsonError("Invalid request body", 400);
|
|
136
|
+
const parsed = JSON.parse(raw);
|
|
137
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
138
|
+
return jsonError("Invalid request body", 400);
|
|
139
|
+
}
|
|
140
|
+
body = parsed;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return jsonError("Invalid request body", 400);
|
|
144
|
+
}
|
|
145
|
+
switch (action) {
|
|
146
|
+
case "start":
|
|
147
|
+
return this.handleStart(request, caller.did, instanceDid);
|
|
148
|
+
case "dry-run":
|
|
149
|
+
return this.handleDryRun(caller.did, body, instanceDid);
|
|
150
|
+
case "commit":
|
|
151
|
+
return this.handleCommit(caller.did, body, request, instanceDid);
|
|
152
|
+
default:
|
|
153
|
+
return jsonError("Not found", 404);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async verifyCaller(request) {
|
|
157
|
+
const cookie = request.headers.get("Cookie") ?? "";
|
|
158
|
+
const match = new RegExp(`${this.cookieName}=([^;]+)`).exec(cookie);
|
|
159
|
+
if (!match?.[1])
|
|
160
|
+
return null;
|
|
161
|
+
const payload = await verifyJWT(match[1], this.jwtSecret);
|
|
162
|
+
if (!payload || typeof payload.did !== "string" || !payload.did)
|
|
163
|
+
return null;
|
|
164
|
+
return { did: payload.did };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Boolean-only existence signal. `self` is the session DID — query/body
|
|
168
|
+
* `did`/`email` are not read (existence oracle). Users are global; this
|
|
169
|
+
* does not take instanceDid.
|
|
170
|
+
*/
|
|
171
|
+
async handleCandidate(selfDid) {
|
|
172
|
+
const mergeCandidate = await this.store.hasVerifiedEmailMergeCandidate(selfDid);
|
|
173
|
+
return jsonResponse({ mergeCandidate });
|
|
174
|
+
}
|
|
175
|
+
async handleStart(request, callerDid, instanceDid) {
|
|
176
|
+
const user = await this.store.getUserByDid(callerDid);
|
|
177
|
+
if (!user)
|
|
178
|
+
return jsonError("Authentication required", 401);
|
|
179
|
+
if (user.mergedInto)
|
|
180
|
+
return jsonError("This account has already been merged", 403);
|
|
181
|
+
const started = await this.store.createMergeStart(callerDid);
|
|
182
|
+
// Gate Secure on https like the other handlers — over plain http the browser
|
|
183
|
+
// drops a Secure cookie, so the challenge would never come back on commit.
|
|
184
|
+
const isSecure = new URL(request.url).protocol === "https:";
|
|
185
|
+
const cookie = `${MERGE_CHALLENGE_COOKIE}=${started.challenge}; Path=/; Max-Age=${MERGE_START_TTL_SECONDS}; SameSite=Lax;${isSecure ? " Secure;" : ""} HttpOnly`;
|
|
186
|
+
this.logger.info({
|
|
187
|
+
message: "account merge started",
|
|
188
|
+
mod: "account-merge",
|
|
189
|
+
intoDid: callerDid,
|
|
190
|
+
instanceDid,
|
|
191
|
+
});
|
|
192
|
+
await this.store.createAuditLog({
|
|
193
|
+
action: "account.merge.start",
|
|
194
|
+
operatorDid: callerDid,
|
|
195
|
+
targetDid: callerDid,
|
|
196
|
+
metadata: { intoDid: callerDid },
|
|
197
|
+
instanceDid: instanceDid && instanceDid !== "_global_" ? instanceDid : undefined,
|
|
198
|
+
});
|
|
199
|
+
return jsonResponse({ challenge: started.challenge, intoDid: callerDid, expiresAt: started.expiresAt }, 200, { "Set-Cookie": cookie });
|
|
200
|
+
}
|
|
201
|
+
async loadUsableIntent(callerDid, body) {
|
|
202
|
+
const token = typeof body.mergeIntent === "string" ? body.mergeIntent.trim() : "";
|
|
203
|
+
if (!token)
|
|
204
|
+
return jsonError("Merge intent required", 403);
|
|
205
|
+
const tokenHash = await hashMergeToken(token);
|
|
206
|
+
const intent = await this.store.getMergeIntent(tokenHash);
|
|
207
|
+
if (!intent)
|
|
208
|
+
return jsonError("Invalid or expired merge intent", 400);
|
|
209
|
+
const status = intentIsUsable(intent);
|
|
210
|
+
if (status === "used")
|
|
211
|
+
return jsonError("Merge intent already used", 403);
|
|
212
|
+
if (status === "expired")
|
|
213
|
+
return jsonError("Merge intent expired", 403);
|
|
214
|
+
if (intent.intoDid !== callerDid)
|
|
215
|
+
return jsonError("Merge intent does not belong to this session", 403);
|
|
216
|
+
return { intent };
|
|
217
|
+
}
|
|
218
|
+
async handleDryRun(callerDid, body, instanceDid) {
|
|
219
|
+
const loaded = await this.loadUsableIntent(callerDid, body);
|
|
220
|
+
if (loaded instanceof Response)
|
|
221
|
+
return loaded;
|
|
222
|
+
const snapshot = await this.store.planAccountMerge(loaded.intent.fromDid, loaded.intent.intoDid);
|
|
223
|
+
await this.store.createAuditLog({
|
|
224
|
+
action: "account.merge.dry_run",
|
|
225
|
+
operatorDid: callerDid,
|
|
226
|
+
targetDid: loaded.intent.fromDid,
|
|
227
|
+
metadata: {
|
|
228
|
+
fromDid: loaded.intent.fromDid,
|
|
229
|
+
intoDid: loaded.intent.intoDid,
|
|
230
|
+
credentialCount: snapshot.credentials.length,
|
|
231
|
+
skippedConflictCount: snapshot.skippedConflicts.length,
|
|
232
|
+
},
|
|
233
|
+
instanceDid: instanceDid && instanceDid !== "_global_" ? instanceDid : undefined,
|
|
234
|
+
});
|
|
235
|
+
return jsonResponse(toMergeConfirmPlan(snapshot));
|
|
236
|
+
}
|
|
237
|
+
async handleCommit(callerDid, body, request, instanceDid) {
|
|
238
|
+
const loaded = await this.loadUsableIntent(callerDid, body);
|
|
239
|
+
if (loaded instanceof Response)
|
|
240
|
+
return loaded;
|
|
241
|
+
const result = await this.store.commitAccountMerge(loaded.intent.tokenHash, callerDid);
|
|
242
|
+
if (!result.ok)
|
|
243
|
+
return jsonError(result.error, result.status);
|
|
244
|
+
const snapshotHash = await hashSnapshot(result.snapshot);
|
|
245
|
+
await this.store.createAuditLog({
|
|
246
|
+
action: "account.merge",
|
|
247
|
+
operatorDid: callerDid,
|
|
248
|
+
targetDid: result.snapshot.fromDid,
|
|
249
|
+
metadata: {
|
|
250
|
+
fromDid: result.snapshot.fromDid,
|
|
251
|
+
intoDid: result.snapshot.intoDid,
|
|
252
|
+
snapshotHash,
|
|
253
|
+
credentials: result.snapshot.credentials.map((c) => c.did),
|
|
254
|
+
skipped: result.snapshot.skippedConflicts.length,
|
|
255
|
+
},
|
|
256
|
+
ip: request.headers.get("CF-Connecting-IP") ?? undefined,
|
|
257
|
+
instanceDid: instanceDid && instanceDid !== "_global_" ? instanceDid : undefined,
|
|
258
|
+
});
|
|
259
|
+
const plan = toMergePlanView(result.snapshot);
|
|
260
|
+
return jsonResponse({ ok: true, ...plan, snapshotHash });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=account-merge-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-merge-handler.js","sourceRoot":"","sources":["../../src/handlers/account-merge-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
* const caller = await auth.verifyFull(req); // auth gate
|
|
12
12
|
* if (!caller) return auth.unauthorized(req);
|
|
13
13
|
*/
|
|
14
|
+
import type { GetAccountState } from "../identity/account-state.js";
|
|
14
15
|
import type { AuthEntrypointInterface } from "../identity/auth-entrypoint.js";
|
|
15
16
|
import { type Logger } from "../logger.js";
|
|
17
|
+
import type { AppInfo } from "../package-branding.js";
|
|
16
18
|
import type { CallerIdentity } from "../types.js";
|
|
17
19
|
export interface AuthHandlerOptions {
|
|
18
20
|
/** D1 database binding. */
|
|
@@ -42,11 +44,7 @@ export interface AuthHandlerOptions {
|
|
|
42
44
|
* `appSk` (the per-instance / standalone canonical secret). */
|
|
43
45
|
csrfSecret?: string;
|
|
44
46
|
/** Application info shown to the wallet during DID Connect. */
|
|
45
|
-
appInfo?:
|
|
46
|
-
name: string;
|
|
47
|
-
description?: string;
|
|
48
|
-
icon?: string;
|
|
49
|
-
};
|
|
47
|
+
appInfo?: AppInfo;
|
|
50
48
|
/** Resend API key for email verification. Optional — can also be configured via Admin Settings (D1 email:config). */
|
|
51
49
|
resendApiKey?: string;
|
|
52
50
|
/** From address for verification emails. Optional — can also be configured via Admin Settings (D1 email:config). */
|
|
@@ -100,6 +98,12 @@ export interface AuthHandlerOptions {
|
|
|
100
98
|
* tests never touch the network; defaults to the global `fetch`.
|
|
101
99
|
*/
|
|
102
100
|
cimdFetch?: typeof fetch;
|
|
101
|
+
/**
|
|
102
|
+
* Host-injected chain account-state lookup for wallet login. Optional:
|
|
103
|
+
* omitted → today's behaviour. Forwarded into DIDConnectHandler.
|
|
104
|
+
* Always invoked as `getAccountState({ address, traceMigration: false })`.
|
|
105
|
+
*/
|
|
106
|
+
getAccountState?: GetAccountState;
|
|
103
107
|
}
|
|
104
108
|
/** Membership record from the memberships table. */
|
|
105
109
|
export interface StoredMembership {
|
|
@@ -123,9 +127,12 @@ export interface AuthHandler {
|
|
|
123
127
|
* Handle auth-related routes: passkey API, team API, admin/invite pages, logout.
|
|
124
128
|
* Returns a Response if the route matched, or null to let the caller continue.
|
|
125
129
|
* @param context Optional instance context — instanceDid is passed to team/access key handlers.
|
|
130
|
+
* `isServiceContext` has always been honored by the implementation; declaring it
|
|
131
|
+
* here spares callers a cast to `Parameters<typeof route>[1]` to pass it.
|
|
126
132
|
*/
|
|
127
133
|
route(request: Request, context?: {
|
|
128
134
|
instanceDid?: string;
|
|
135
|
+
isServiceContext?: boolean;
|
|
129
136
|
}): Promise<Response | null>;
|
|
130
137
|
/** Verify JWT from cookie — lightweight, no DB query. */
|
|
131
138
|
verify(request: Request): Promise<CallerIdentity | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/auth-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAM9E,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/auth-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,7 @@ import { buildHomepageHTML } from "../pages/homepage.js";
|
|
|
26
26
|
import { D1Store } from "../store/d1-store.js";
|
|
27
27
|
import { AccessKeyConnectHandler } from "./access-key-connect-handler.js";
|
|
28
28
|
import { AccessKeyHandler } from "./access-key-handler.js";
|
|
29
|
+
import { AccountMergeHandler } from "./account-merge-handler.js";
|
|
29
30
|
import { AdminInstanceHandler } from "./admin-instance-handler.js";
|
|
30
31
|
import { AvatarHandler } from "./avatar-handler.js";
|
|
31
32
|
import { BlockletJsHandler } from "./blocklet-js-handler.js";
|
|
@@ -43,6 +44,7 @@ export function createAuthHandler(options) {
|
|
|
43
44
|
const store = new D1Store(options.db, { readSession: options.readSession });
|
|
44
45
|
const jwtExpiresIn = options.jwtExpiresIn ?? 7 * 24 * 60 * 60;
|
|
45
46
|
const cookieName = options.cookieName ?? "login_token";
|
|
47
|
+
const appInfo = options.appInfo ?? { name: options.appName };
|
|
46
48
|
const defaultInstanceDid = options.instanceDid
|
|
47
49
|
|| (options.appSk ? fromSecretKey(normalizeSecretKey(options.appSk), APP_WALLET_TYPE).address : undefined);
|
|
48
50
|
// App wallet for signResponse — used to sign session/refresh responses
|
|
@@ -50,7 +52,7 @@ export function createAuthHandler(options) {
|
|
|
50
52
|
const passkey = new Auth({
|
|
51
53
|
store,
|
|
52
54
|
jwtSecret: options.jwtSecret,
|
|
53
|
-
rpName:
|
|
55
|
+
rpName: appInfo.name,
|
|
54
56
|
rpID: options.rpID,
|
|
55
57
|
jwtExpiresIn,
|
|
56
58
|
cookieName,
|
|
@@ -63,7 +65,7 @@ export function createAuthHandler(options) {
|
|
|
63
65
|
r2: options.r2,
|
|
64
66
|
resendApiKey: options.resendApiKey,
|
|
65
67
|
emailFrom: options.emailFrom,
|
|
66
|
-
rpName:
|
|
68
|
+
rpName: appInfo.name,
|
|
67
69
|
logger,
|
|
68
70
|
});
|
|
69
71
|
const accessKeys = new AccessKeyHandler({ store, passkey });
|
|
@@ -96,11 +98,12 @@ export function createAuthHandler(options) {
|
|
|
96
98
|
jwtExpiresIn,
|
|
97
99
|
cookieName,
|
|
98
100
|
rpID: options.rpID,
|
|
99
|
-
appInfo
|
|
101
|
+
appInfo,
|
|
100
102
|
r2: options.r2,
|
|
101
103
|
delegator: options.federationDelegator,
|
|
102
104
|
delegation: options.federationDelegation,
|
|
103
105
|
logger,
|
|
106
|
+
getAccountState: options.getAccountState,
|
|
104
107
|
})
|
|
105
108
|
: null;
|
|
106
109
|
// OAuth: enabled when appSk is provided (configs come from D1 settings)
|
|
@@ -119,6 +122,13 @@ export function createAuthHandler(options) {
|
|
|
119
122
|
logger,
|
|
120
123
|
})
|
|
121
124
|
: null;
|
|
125
|
+
const accountMerge = new AccountMergeHandler({
|
|
126
|
+
store,
|
|
127
|
+
jwtSecret: options.jwtSecret,
|
|
128
|
+
cookieName,
|
|
129
|
+
logger,
|
|
130
|
+
appDid: defaultInstanceDid,
|
|
131
|
+
});
|
|
122
132
|
// Email login: enabled when appSk is provided.
|
|
123
133
|
// resendApiKey/emailFrom can come from env vars OR D1 email:config (resolved at runtime).
|
|
124
134
|
const emailLogin = options.appSk
|
|
@@ -135,6 +145,7 @@ export function createAuthHandler(options) {
|
|
|
135
145
|
authMaster: options.authMaster,
|
|
136
146
|
r2: options.r2,
|
|
137
147
|
logger,
|
|
148
|
+
appName: appInfo.name,
|
|
138
149
|
})
|
|
139
150
|
: null;
|
|
140
151
|
// Ticket handler: always enabled (used for federation ticket exchange)
|
|
@@ -164,6 +175,7 @@ export function createAuthHandler(options) {
|
|
|
164
175
|
r2: options.r2,
|
|
165
176
|
instanceDid: defaultInstanceDid,
|
|
166
177
|
rpName: options.appName,
|
|
178
|
+
appInfo,
|
|
167
179
|
ogGenerator: options.ogGenerator,
|
|
168
180
|
});
|
|
169
181
|
// Avatar: deterministic avatar endpoint (R2 → DB URL → DID SVG fallback)
|
|
@@ -177,7 +189,7 @@ export function createAuthHandler(options) {
|
|
|
177
189
|
appDid: options.appDid,
|
|
178
190
|
instanceDid: defaultInstanceDid,
|
|
179
191
|
serverVersion: options.serverVersion,
|
|
180
|
-
|
|
192
|
+
appInfo,
|
|
181
193
|
})
|
|
182
194
|
: null;
|
|
183
195
|
// Build the static methods array; email is resolved dynamically at request time
|
|
@@ -197,9 +209,14 @@ export function createAuthHandler(options) {
|
|
|
197
209
|
let configSourceDid = effectiveDid;
|
|
198
210
|
let masterOAuthOrigin;
|
|
199
211
|
let configSettings;
|
|
212
|
+
// Branding is read from the LOCAL instance even in federation — a member site
|
|
213
|
+
// shows its own name, only login *methods* and theme come from the Master
|
|
214
|
+
// (same rule passkey-handler's getLoginPage applies).
|
|
215
|
+
let localSettingsMap;
|
|
200
216
|
if (effectiveDid) {
|
|
201
217
|
const localSettings = await store.listSettings(effectiveDid);
|
|
202
218
|
const localMap = new Map(localSettings.map((s) => [s.key, s.value]));
|
|
219
|
+
localSettingsMap = localMap;
|
|
203
220
|
// Federation check (from local settings map — no extra D1 query)
|
|
204
221
|
const fedRole = localMap.get("federation:role");
|
|
205
222
|
const fedEnabled = localMap.get("federation:enabled");
|
|
@@ -291,14 +308,34 @@ export function createAuthHandler(options) {
|
|
|
291
308
|
if (idx >= 0)
|
|
292
309
|
methods.splice(idx, 1);
|
|
293
310
|
}
|
|
294
|
-
|
|
311
|
+
// The app's display name, resolved the SAME way every other surface resolves
|
|
312
|
+
// it: operator-stored `app:branding.name` first, then `appInfo.name` (which
|
|
313
|
+
// already carries the host-supplied package name and the deployment default).
|
|
314
|
+
//
|
|
315
|
+
// This is returned rather than left out because AccessKeyConnectHandler takes
|
|
316
|
+
// this object as its WHOLE page-options value. Omitting appName here is what
|
|
317
|
+
// made the authorize page fall through to its generic i18n title
|
|
318
|
+
// ("Access Key Authorization") on every deployment, no matter how the app was
|
|
319
|
+
// branded — a page that names the wrong app is exactly the prompt a user
|
|
320
|
+
// should refuse to approve.
|
|
321
|
+
let appName = appInfo.name;
|
|
322
|
+
const localBrandingRaw = localSettingsMap?.get("app:branding");
|
|
323
|
+
if (localBrandingRaw) {
|
|
324
|
+
try {
|
|
325
|
+
const b = JSON.parse(localBrandingRaw);
|
|
326
|
+
if (typeof b.name === "string" && b.name)
|
|
327
|
+
appName = b.name;
|
|
328
|
+
}
|
|
329
|
+
catch { /* keep appInfo.name */ }
|
|
330
|
+
}
|
|
331
|
+
return { methods, oauthProviders, masterOAuthOrigin, appName };
|
|
295
332
|
}
|
|
296
333
|
/** Render the homepage portal page. */
|
|
297
334
|
async function serveHomepage(request, instanceDid) {
|
|
298
335
|
const locale = detectLocale(request);
|
|
299
336
|
const theme = detectTheme(request);
|
|
300
|
-
let appName =
|
|
301
|
-
let appDescription = "";
|
|
337
|
+
let appName = appInfo.name;
|
|
338
|
+
let appDescription = appInfo.description ?? "";
|
|
302
339
|
const version = options.serverVersion ?? "1.0.0";
|
|
303
340
|
const brandingDid = instanceDid || defaultInstanceDid;
|
|
304
341
|
if (brandingDid) {
|
|
@@ -347,6 +384,7 @@ export function createAuthHandler(options) {
|
|
|
347
384
|
pathname.startsWith("/.well-known/service/api/team/profile/") ||
|
|
348
385
|
pathname.startsWith("/.well-known/service/api/team/invitations/") ||
|
|
349
386
|
pathname.startsWith("/.well-known/service/api/did/") ||
|
|
387
|
+
pathname.startsWith("/.well-known/service/api/wallet/") ||
|
|
350
388
|
pathname.startsWith("/.well-known/service/api/passkey") ||
|
|
351
389
|
pathname.startsWith("/.well-known/service/api/oauth") ||
|
|
352
390
|
pathname.startsWith("/.well-known/service/oauth/") ||
|
|
@@ -364,7 +402,9 @@ export function createAuthHandler(options) {
|
|
|
364
402
|
pathname === "/.well-known/service/oauth/authorize" ||
|
|
365
403
|
pathname === "/.well-known/service/oauth/register" ||
|
|
366
404
|
pathname === "/.well-known/service/oauth/device_authorization" ||
|
|
367
|
-
pathname === "/.well-known/service/oauth/token"
|
|
405
|
+
pathname === "/.well-known/service/oauth/token" ||
|
|
406
|
+
// Dual-auth merge: /.well-known/service/api/account/merge/{candidate,start,dry-run,commit}
|
|
407
|
+
pathname.startsWith("/.well-known/service/api/account/merge")) {
|
|
368
408
|
return true;
|
|
369
409
|
}
|
|
370
410
|
// Public team invitation endpoints — info is read-only and handler-authorized;
|
|
@@ -744,6 +784,12 @@ export function createAuthHandler(options) {
|
|
|
744
784
|
return jsonResponse({ ok: false, error: "DB unreachable" }, 503);
|
|
745
785
|
}
|
|
746
786
|
}
|
|
787
|
+
// Account merge (dual-auth). Three routes: start / dry-run / commit.
|
|
788
|
+
{
|
|
789
|
+
const r = await accountMerge.fetch(request, instanceDid || defaultInstanceDid);
|
|
790
|
+
if (r)
|
|
791
|
+
return r;
|
|
792
|
+
}
|
|
747
793
|
// DID Connect routes (wallet auth via WalletHandlers + complete endpoint)
|
|
748
794
|
if (didConnect) {
|
|
749
795
|
const r = await didConnect.fetch(request, instanceDid || defaultInstanceDid);
|