@unidy.io/sdk 1.2.0-alpha9 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/_commonjsHelpers-CFO10eej.js +10 -0
- package/dist/cjs/_commonjsHelpers-CFO10eej.js.map +1 -0
- package/dist/cjs/app-globals-C-Wl5lPS.js +10 -0
- package/dist/cjs/app-globals-C-Wl5lPS.js.map +1 -0
- package/dist/cjs/{auth-store-DPmGKHZ2.js → auth-store-0vv3uOib.js} +4 -4
- package/dist/cjs/{auth-store-DPmGKHZ2.js.map → auth-store-0vv3uOib.js.map} +1 -1
- package/dist/cjs/component-DLxnZCW6.js +34 -0
- package/dist/cjs/component-DLxnZCW6.js.map +1 -0
- package/dist/cjs/component-utils-XXctnOM9.js +38 -0
- package/dist/cjs/component-utils-XXctnOM9.js.map +1 -0
- package/dist/cjs/de-BWF6Glzg.js +704 -0
- package/dist/cjs/de-BWF6Glzg.js.map +1 -0
- package/dist/cjs/en-GB-DhD5mdQw.js +119 -0
- package/dist/cjs/en-GB-DhD5mdQw.js.map +1 -0
- package/dist/cjs/{flash-store-gbSYhPAV.js → flash-store-CR6Umh1O.js} +3 -3
- package/dist/cjs/{flash-store-gbSYhPAV.js.map → flash-store-CR6Umh1O.js.map} +1 -1
- package/dist/cjs/fr-j2wwoj-A.js +577 -0
- package/dist/cjs/fr-j2wwoj-A.js.map +1 -0
- package/dist/cjs/has-slot-content-CfJbU4t-.js +37 -0
- package/dist/cjs/has-slot-content-CfJbU4t-.js.map +1 -0
- package/dist/cjs/{i18n-D5j_Zl-4.js → i18n-ClWrNmGh.js} +100 -4
- package/dist/cjs/{i18n-D5j_Zl-4.js.map → i18n-ClWrNmGh.js.map} +1 -1
- package/dist/cjs/{index-B325yXfO.js → index-2Fz3r5o0.js} +5 -41
- package/dist/cjs/index-2Fz3r5o0.js.map +1 -0
- package/dist/cjs/{index-yaeiYlfa.js → index-C6ZBKFYr.js} +3 -3
- package/dist/cjs/{index-yaeiYlfa.js.map → index-C6ZBKFYr.js.map} +1 -1
- package/dist/cjs/{index-BzPYBLYC.js → index-CpPKy1CZ.js} +1170 -1087
- package/dist/cjs/index-CpPKy1CZ.js.map +1 -0
- package/dist/cjs/index.cjs.js +24 -11
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +3 -3
- package/dist/cjs/{newsletter-helpers-hdDC5X-V.js → newsletter-helpers-BHvOI8M4.js} +46 -9
- package/dist/cjs/newsletter-helpers-BHvOI8M4.js.map +1 -0
- package/dist/cjs/{newsletter-store-CupsLgO9.js → newsletter-store-22Jswiqe.js} +5 -3
- package/dist/cjs/newsletter-store-22Jswiqe.js.map +1 -0
- package/dist/cjs/nl-BE-yKvOp1-G.js +542 -0
- package/dist/cjs/nl-BE-yKvOp1-G.js.map +1 -0
- package/dist/cjs/{profile-helpers-Bprrm-Xl.js → profile-helpers-BBpAqHjK.js} +4 -4
- package/dist/cjs/{profile-helpers-Bprrm-Xl.js.map → profile-helpers-BBpAqHjK.js.map} +1 -1
- package/dist/cjs/{profile-store-C_q-TuA_.js → profile-store-CQEQhPQD.js} +4 -4
- package/dist/cjs/{profile-store-C_q-TuA_.js.map → profile-store-CQEQhPQD.js.map} +1 -1
- package/dist/cjs/redirect-with-token-wupYX97S.js +37 -0
- package/dist/cjs/redirect-with-token-wupYX97S.js.map +1 -0
- package/dist/cjs/ro-CXq9d1lv.js +578 -0
- package/dist/cjs/ro-CXq9d1lv.js.map +1 -0
- package/dist/cjs/sdk.cjs.js +3 -3
- package/dist/cjs/sv-CMln4V33.js +597 -0
- package/dist/cjs/sv-CMln4V33.js.map +1 -0
- package/dist/cjs/u-conditional-render.cjs.entry.js +14 -14
- package/dist/cjs/u-conditional-render.entry.cjs.js.map +1 -1
- package/dist/cjs/u-config.cjs.entry.js +24 -11
- package/dist/cjs/u-config.entry.cjs.js.map +1 -1
- package/dist/cjs/u-email-field.cjs.entry.js +7 -7
- package/dist/cjs/u-error-message.cjs.entry.js +49 -22
- package/dist/cjs/u-error-message.entry.cjs.js.map +1 -1
- package/dist/cjs/u-field.u-raw-field.entry.cjs.js.map +1 -1
- package/dist/cjs/u-field_2.cjs.entry.js +124 -12
- package/dist/cjs/u-flash-message.cjs.entry.js +3 -3
- package/dist/cjs/u-full-profile.cjs.entry.js +6 -6
- package/dist/cjs/u-jump-to-service.cjs.entry.js +23 -44
- package/dist/cjs/u-jump-to-service.entry.cjs.js.map +1 -1
- package/dist/cjs/u-jump-to-unidy.cjs.entry.js +22 -43
- package/dist/cjs/u-jump-to-unidy.entry.cjs.js.map +1 -1
- package/dist/cjs/u-logout-button.u-signed-in.entry.cjs.js.map +1 -1
- package/dist/cjs/u-logout-button_2.cjs.entry.js +15 -22
- package/dist/cjs/u-magic-code-field.cjs.entry.js +8 -9
- package/dist/cjs/u-magic-code-field.entry.cjs.js.map +1 -1
- package/dist/cjs/u-missing-field.cjs.entry.js +6 -5
- package/dist/cjs/u-missing-field.entry.cjs.js.map +1 -1
- package/dist/cjs/u-missing-fields-submit-button.cjs.entry.js +16 -14
- package/dist/cjs/u-missing-fields-submit-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-checkbox.cjs.entry.js +11 -12
- package/dist/cjs/u-newsletter-checkbox.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-consent-checkbox.cjs.entry.js +4 -4
- package/dist/cjs/u-newsletter-logout-button.cjs.entry.js +15 -20
- package/dist/cjs/u-newsletter-logout-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-preference-checkbox.cjs.entry.js +11 -12
- package/dist/cjs/u-newsletter-preference-checkbox.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-resend-doi-button.cjs.entry.js +10 -11
- package/dist/cjs/u-newsletter-resend-doi-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-root.cjs.entry.js +45 -22
- package/dist/cjs/u-newsletter-root.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-toggle-subscription-button.cjs.entry.js +11 -12
- package/dist/cjs/u-newsletter-toggle-subscription-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-pagination-button.cjs.entry.js +4 -4
- package/dist/cjs/u-pagination-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-pagination-page.cjs.entry.js +4 -4
- package/dist/cjs/u-pagination-page.entry.cjs.js.map +1 -1
- package/dist/cjs/u-passkey.cjs.entry.js +8 -9
- package/dist/cjs/u-passkey.entry.cjs.js.map +1 -1
- package/dist/cjs/u-password-field.cjs.entry.js +5 -5
- package/dist/cjs/u-profile.u-submit-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-profile_2.cjs.entry.js +31 -33
- package/dist/cjs/u-registration-button.cjs.entry.js +5 -5
- package/dist/cjs/u-reset-password-button.cjs.entry.js +12 -15
- package/dist/cjs/u-reset-password-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-send-magic-code-button.cjs.entry.js +8 -9
- package/dist/cjs/u-send-magic-code-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-signin-root.cjs.entry.js +6 -8
- package/dist/cjs/u-signin-root.entry.cjs.js.map +1 -1
- package/dist/cjs/u-signin-step.cjs.entry.js +17 -21
- package/dist/cjs/u-signin-step.entry.cjs.js.map +1 -1
- package/dist/cjs/u-social-login-button.cjs.entry.js +16 -15
- package/dist/cjs/u-social-login-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-spinner.cjs.entry.js +3 -3
- package/dist/cjs/u-spinner.entry.cjs.js.map +1 -1
- package/dist/cjs/u-ticketable-export.cjs.entry.js +76 -0
- package/dist/cjs/u-ticketable-export.entry.cjs.js.map +1 -0
- package/dist/cjs/u-ticketable-list-D3M8iA-g.js +3991 -0
- package/dist/cjs/u-ticketable-list-D3M8iA-g.js.map +1 -0
- package/dist/cjs/u-ticketable-list.cjs.entry.js +11 -6118
- package/dist/cjs/u-ticketable-list.entry.cjs.js.map +1 -1
- package/dist/cjs/{unidy-store-BGnWn9pc.js → unidy-store-Bvnl24i9.js} +3 -3
- package/dist/cjs/{unidy-store-BGnWn9pc.js.map → unidy-store-Bvnl24i9.js.map} +1 -1
- package/dist/collection/api/base-service.js.map +1 -1
- package/dist/collection/api/client.js.map +1 -1
- package/dist/collection/api/index.js +6 -6
- package/dist/collection/api/index.js.map +1 -1
- package/dist/collection/api/standalone.js +88 -39
- package/dist/collection/api/standalone.js.map +1 -1
- package/dist/collection/auth/api/auth.js.map +1 -1
- package/dist/collection/auth/api/schemas.js +5 -5
- package/dist/collection/auth/api/schemas.js.map +1 -1
- package/dist/collection/auth/auth-helpers.js +7 -8
- package/dist/collection/auth/auth-helpers.js.map +1 -1
- package/dist/collection/auth/auth.js +1 -0
- package/dist/collection/auth/auth.js.map +1 -1
- package/dist/collection/auth/components/jump-to-service/jump-to-service.js +20 -40
- package/dist/collection/auth/components/jump-to-service/jump-to-service.js.map +1 -1
- package/dist/collection/auth/components/jump-to-unidy/jump-to-unidy.js +20 -39
- package/dist/collection/auth/components/jump-to-unidy/jump-to-unidy.js.map +1 -1
- package/dist/collection/auth/components/logout-button/logout-button.js +7 -11
- package/dist/collection/auth/components/logout-button/logout-button.js.map +1 -1
- package/dist/collection/auth/components/missing-field/missing-field.js +25 -1
- package/dist/collection/auth/components/missing-field/missing-field.js.map +1 -1
- package/dist/collection/auth/components/missing-fields-submit-button/missing-fields-submit-button.js +33 -7
- package/dist/collection/auth/components/missing-fields-submit-button/missing-fields-submit-button.js.map +1 -1
- package/dist/collection/auth/components/password-field/password-field.js +1 -1
- package/dist/collection/auth/components/reset-pass-button/reset-pass-button.js +6 -8
- package/dist/collection/auth/components/reset-pass-button/reset-pass-button.js.map +1 -1
- package/dist/collection/auth/components/signed-in/signed-in.js +2 -5
- package/dist/collection/auth/components/signed-in/signed-in.js.map +1 -1
- package/dist/collection/auth/components/signin-root/signin-root.js +2 -5
- package/dist/collection/auth/components/signin-root/signin-root.js.map +1 -1
- package/dist/collection/auth/components/signin-step/signin-step.js +9 -13
- package/dist/collection/auth/components/signin-step/signin-step.js.map +1 -1
- package/dist/collection/auth/components/social-logins/social-login-button.css +1 -1
- package/dist/collection/auth/components/social-logins/social-login-button.js +11 -12
- package/dist/collection/auth/components/social-logins/social-login-button.js.map +1 -1
- package/dist/collection/auth/components/submit-button/auth-submit-button.js +10 -0
- package/dist/collection/auth/components/submit-button/auth-submit-button.js.map +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/locales/de.json +16 -0
- package/dist/collection/locales/en.json +16 -0
- package/dist/collection/locales/fr.json +16 -0
- package/dist/collection/locales/it.json +16 -0
- package/dist/collection/locales/nl_be.json +16 -0
- package/dist/collection/locales/ro.json +16 -0
- package/dist/collection/logger.js +0 -37
- package/dist/collection/logger.js.map +1 -1
- package/dist/collection/newsletter/api/newsletters.js +19 -18
- package/dist/collection/newsletter/api/newsletters.js.map +1 -1
- package/dist/collection/newsletter/components/consent-checkbox/consent-checkbox.js +1 -1
- package/dist/collection/newsletter/components/logout-button/logout-button.js +6 -10
- package/dist/collection/newsletter/components/logout-button/logout-button.js.map +1 -1
- package/dist/collection/newsletter/components/newsletter-checkbox/newsletter-checkbox.js +1 -1
- package/dist/collection/newsletter/components/newsletter-root/newsletter-root.js +65 -10
- package/dist/collection/newsletter/components/newsletter-root/newsletter-root.js.map +1 -1
- package/dist/collection/newsletter/components/preference-checkbox/preference-checkbox.js +1 -1
- package/dist/collection/newsletter/components/toggle-subscription-button/toggle-subscription-button.js +1 -1
- package/dist/collection/newsletter/newsletter-helpers.js +39 -2
- package/dist/collection/newsletter/newsletter-helpers.js.map +1 -1
- package/dist/collection/newsletter/store/newsletter-store.js +2 -0
- package/dist/collection/newsletter/store/newsletter-store.js.map +1 -1
- package/dist/collection/profile/api/profile.js.map +1 -1
- package/dist/collection/profile/api/schemas.js +1 -1
- package/dist/collection/profile/api/schemas.js.map +1 -1
- package/dist/collection/profile/components/field/field.js +3 -1
- package/dist/collection/profile/components/field/field.js.map +1 -1
- package/dist/collection/profile/components/full-profile/full-profile.js +1 -1
- package/dist/collection/profile/components/raw-field/raw-field.js +40 -7
- package/dist/collection/profile/components/raw-field/raw-field.js.map +1 -1
- package/dist/collection/profile/store/profile-store.js +1 -1
- package/dist/collection/profile/store/profile-store.js.map +1 -1
- package/dist/collection/shared/base/component.js +28 -0
- package/dist/collection/shared/base/component.js.map +1 -0
- package/dist/collection/shared/base/has-slot-content.js +31 -0
- package/dist/collection/shared/base/has-slot-content.js.map +1 -0
- package/dist/collection/shared/component-utils.js +23 -27
- package/dist/collection/shared/component-utils.js.map +1 -1
- package/dist/collection/shared/components/conditional-render/conditional-render.js +4 -5
- package/dist/collection/shared/components/conditional-render/conditional-render.js.map +1 -1
- package/dist/collection/shared/components/config/config.js +18 -5
- package/dist/collection/shared/components/config/config.js.map +1 -1
- package/dist/collection/shared/components/email-field/email-field.js +1 -1
- package/dist/collection/shared/components/error-message/error-message.css +1 -1
- package/dist/collection/shared/components/error-message/error-message.js +44 -17
- package/dist/collection/shared/components/error-message/error-message.js.map +1 -1
- package/dist/collection/shared/components/spinner/spinner.css +1 -1
- package/dist/collection/shared/components/spinner/spinner.js +1 -1
- package/dist/collection/shared/components/submit-button/submit-button.css +1 -1
- package/dist/collection/shared/components/submit-button/submit-button.js +12 -23
- package/dist/collection/shared/components/submit-button/submit-button.js.map +1 -1
- package/dist/collection/shared/context-utils.js +96 -0
- package/dist/collection/shared/context-utils.js.map +1 -0
- package/dist/collection/shared/utils/redirect-with-token.js +30 -0
- package/dist/collection/shared/utils/redirect-with-token.js.map +1 -0
- package/dist/collection/shared/utils/url-utils.js +25 -0
- package/dist/collection/shared/utils/url-utils.js.map +1 -0
- package/dist/collection/ticketable/api/schemas.js +10 -2
- package/dist/collection/ticketable/api/schemas.js.map +1 -1
- package/dist/collection/ticketable/api/subscriptions.js +22 -1
- package/dist/collection/ticketable/api/subscriptions.js.map +1 -1
- package/dist/collection/ticketable/api/tickets.js +22 -1
- package/dist/collection/ticketable/api/tickets.js.map +1 -1
- package/dist/collection/ticketable/components/pagination/pagination-button.js +3 -5
- package/dist/collection/ticketable/components/pagination/pagination-button.js.map +1 -1
- package/dist/collection/ticketable/components/pagination/pagination-page.js +3 -5
- package/dist/collection/ticketable/components/pagination/pagination-page.js.map +1 -1
- package/dist/collection/ticketable/components/ticketable-export/ticketable-export.js +175 -0
- package/dist/collection/ticketable/components/ticketable-export/ticketable-export.js.map +1 -0
- package/dist/collection/ticketable/components/ticketable-list/ticketable-list.js +163 -25
- package/dist/collection/ticketable/components/ticketable-list/ticketable-list.js.map +1 -1
- package/dist/collection/ticketable/index.js +1 -0
- package/dist/collection/ticketable/index.js.map +1 -1
- package/dist/components/_commonjsHelpers.js +8 -0
- package/dist/components/_commonjsHelpers.js.map +1 -0
- package/dist/components/component-utils.js +25 -28
- package/dist/components/component-utils.js.map +1 -1
- package/dist/components/component.js +33 -0
- package/dist/components/component.js.map +1 -0
- package/dist/components/de.js +702 -0
- package/dist/components/de.js.map +1 -0
- package/dist/components/en-GB.js +117 -0
- package/dist/components/en-GB.js.map +1 -0
- package/dist/components/field.js +3 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/fr.js +575 -0
- package/dist/components/fr.js.map +1 -0
- package/dist/components/has-slot-content.js +35 -0
- package/dist/components/has-slot-content.js.map +1 -0
- package/dist/components/i18n.js +96 -0
- package/dist/components/i18n.js.map +1 -1
- package/dist/components/index.js +11 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/index2.js +1158 -1083
- package/dist/components/index2.js.map +1 -1
- package/dist/components/logger.js +1 -39
- package/dist/components/logger.js.map +1 -1
- package/dist/components/newsletter-helpers.js +39 -2
- package/dist/components/newsletter-helpers.js.map +1 -1
- package/dist/components/newsletter-store.js +2 -0
- package/dist/components/newsletter-store.js.map +1 -1
- package/dist/components/nl-BE.js +540 -0
- package/dist/components/nl-BE.js.map +1 -0
- package/dist/components/profile-store.js +1 -1
- package/dist/components/profile-store.js.map +1 -1
- package/dist/components/raw-field.js +116 -7
- package/dist/components/raw-field.js.map +1 -1
- package/dist/components/redirect-with-token.js +35 -0
- package/dist/components/redirect-with-token.js.map +1 -0
- package/dist/components/ro.js +576 -0
- package/dist/components/ro.js.map +1 -0
- package/dist/components/spinner.js +2 -2
- package/dist/components/spinner.js.map +1 -1
- package/dist/components/submit-button.js +21 -24
- package/dist/components/submit-button.js.map +1 -1
- package/dist/components/sv.js +595 -0
- package/dist/components/sv.js.map +1 -0
- package/dist/components/u-conditional-render.js +5 -6
- package/dist/components/u-conditional-render.js.map +1 -1
- package/dist/components/u-config.js +16 -3
- package/dist/components/u-config.js.map +1 -1
- package/dist/components/u-email-field.js +1 -1
- package/dist/components/u-error-message.js +44 -19
- package/dist/components/u-error-message.js.map +1 -1
- package/dist/components/u-full-profile.js +1 -1
- package/dist/components/u-jump-to-service.js +16 -38
- package/dist/components/u-jump-to-service.js.map +1 -1
- package/dist/components/u-jump-to-unidy.js +16 -37
- package/dist/components/u-jump-to-unidy.js.map +1 -1
- package/dist/components/u-logout-button.js +5 -11
- package/dist/components/u-logout-button.js.map +1 -1
- package/dist/components/u-missing-field.js +5 -2
- package/dist/components/u-missing-field.js.map +1 -1
- package/dist/components/u-missing-fields-submit-button.js +10 -8
- package/dist/components/u-missing-fields-submit-button.js.map +1 -1
- package/dist/components/u-newsletter-checkbox.js +1 -1
- package/dist/components/u-newsletter-consent-checkbox.js +1 -1
- package/dist/components/u-newsletter-logout-button.js +6 -12
- package/dist/components/u-newsletter-logout-button.js.map +1 -1
- package/dist/components/u-newsletter-preference-checkbox.js +1 -1
- package/dist/components/u-newsletter-root.js +35 -12
- package/dist/components/u-newsletter-root.js.map +1 -1
- package/dist/components/u-newsletter-toggle-subscription-button.js +1 -1
- package/dist/components/u-pagination-button.js +3 -4
- package/dist/components/u-pagination-button.js.map +1 -1
- package/dist/components/u-pagination-page.js +3 -4
- package/dist/components/u-pagination-page.js.map +1 -1
- package/dist/components/u-reset-password-button.js +4 -8
- package/dist/components/u-reset-password-button.js.map +1 -1
- package/dist/components/u-signed-in.js +3 -6
- package/dist/components/u-signed-in.js.map +1 -1
- package/dist/components/u-signin-root.js +3 -6
- package/dist/components/u-signin-root.js.map +1 -1
- package/dist/components/u-signin-step.js +10 -14
- package/dist/components/u-signin-step.js.map +1 -1
- package/dist/components/u-social-login-button.js +13 -14
- package/dist/components/u-social-login-button.js.map +1 -1
- package/dist/components/u-ticketable-export.d.ts +11 -0
- package/dist/components/u-ticketable-export.js +93 -0
- package/dist/components/u-ticketable-export.js.map +1 -0
- package/dist/components/u-ticketable-list.js +256 -2396
- package/dist/components/u-ticketable-list.js.map +1 -1
- package/dist/esm/_commonjsHelpers-B85MJLTf.js +8 -0
- package/dist/esm/_commonjsHelpers-B85MJLTf.js.map +1 -0
- package/dist/esm/app-globals-J743qnJf.js +8 -0
- package/dist/esm/app-globals-J743qnJf.js.map +1 -0
- package/dist/esm/{auth-store-DBlGNGhq.js → auth-store-CSpEdi46.js} +4 -4
- package/dist/esm/{auth-store-DBlGNGhq.js.map → auth-store-CSpEdi46.js.map} +1 -1
- package/dist/esm/component-qfegGRWr.js +32 -0
- package/dist/esm/component-qfegGRWr.js.map +1 -0
- package/dist/esm/component-utils-WEof9bTg.js +36 -0
- package/dist/esm/component-utils-WEof9bTg.js.map +1 -0
- package/dist/esm/de-C6AnCqsA.js +702 -0
- package/dist/esm/de-C6AnCqsA.js.map +1 -0
- package/dist/esm/en-GB-DO63WPxt.js +117 -0
- package/dist/esm/en-GB-DO63WPxt.js.map +1 -0
- package/dist/esm/{flash-store-Df2YkLTB.js → flash-store-Dn1Bava8.js} +3 -3
- package/dist/esm/{flash-store-Df2YkLTB.js.map → flash-store-Dn1Bava8.js.map} +1 -1
- package/dist/esm/fr-C0oU6-EJ.js +575 -0
- package/dist/esm/fr-C0oU6-EJ.js.map +1 -0
- package/dist/esm/has-slot-content-DSMkJu9G.js +35 -0
- package/dist/esm/has-slot-content-DSMkJu9G.js.map +1 -0
- package/dist/esm/{i18n-Da7S9Oqf.js → i18n-ioyZxWsT.js} +100 -4
- package/dist/esm/{i18n-Da7S9Oqf.js.map → i18n-ioyZxWsT.js.map} +1 -1
- package/dist/esm/{index-FTKB5a1d.js → index-BsJDptgj.js} +4 -40
- package/dist/esm/index-BsJDptgj.js.map +1 -0
- package/dist/esm/{index-BnAYOYR5.js → index-C8kmD3tu.js} +3 -3
- package/dist/esm/{index-BnAYOYR5.js.map → index-C8kmD3tu.js.map} +1 -1
- package/dist/esm/{index-BVlbCQEX.js → index-kgGjfc-n.js} +1163 -1088
- package/dist/esm/index-kgGjfc-n.js.map +1 -0
- package/dist/esm/index.js +18 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/loader.js +4 -4
- package/dist/esm/{newsletter-helpers-fCpxzovf.js → newsletter-helpers-DoKGN_Kq.js} +46 -9
- package/dist/esm/newsletter-helpers-DoKGN_Kq.js.map +1 -0
- package/dist/esm/{newsletter-store-BB618FgS.js → newsletter-store-DpR85vaC.js} +5 -3
- package/dist/esm/newsletter-store-DpR85vaC.js.map +1 -0
- package/dist/esm/nl-BE-C8uPYb_H.js +540 -0
- package/dist/esm/nl-BE-C8uPYb_H.js.map +1 -0
- package/dist/esm/{profile-helpers-CXK2X6Ts.js → profile-helpers-BMJy0ei_.js} +4 -4
- package/dist/esm/{profile-helpers-CXK2X6Ts.js.map → profile-helpers-BMJy0ei_.js.map} +1 -1
- package/dist/esm/{profile-store-CHlSKuTY.js → profile-store-7wBS3gBH.js} +4 -4
- package/dist/esm/{profile-store-CHlSKuTY.js.map → profile-store-7wBS3gBH.js.map} +1 -1
- package/dist/esm/redirect-with-token-StCLJlSp.js +35 -0
- package/dist/esm/redirect-with-token-StCLJlSp.js.map +1 -0
- package/dist/esm/ro-BlDHz7d-.js +576 -0
- package/dist/esm/ro-BlDHz7d-.js.map +1 -0
- package/dist/esm/sdk.js +4 -4
- package/dist/esm/sv-B_Gq29K0.js +595 -0
- package/dist/esm/sv-B_Gq29K0.js.map +1 -0
- package/dist/esm/u-conditional-render.entry.js +14 -14
- package/dist/esm/u-conditional-render.entry.js.map +1 -1
- package/dist/esm/u-config.entry.js +24 -11
- package/dist/esm/u-config.entry.js.map +1 -1
- package/dist/esm/u-email-field.entry.js +7 -7
- package/dist/esm/u-error-message.entry.js +49 -22
- package/dist/esm/u-error-message.entry.js.map +1 -1
- package/dist/esm/u-field.u-raw-field.entry.js.map +1 -1
- package/dist/esm/u-field_2.entry.js +124 -12
- package/dist/esm/u-flash-message.entry.js +3 -3
- package/dist/esm/u-full-profile.entry.js +6 -6
- package/dist/esm/u-jump-to-service.entry.js +23 -44
- package/dist/esm/u-jump-to-service.entry.js.map +1 -1
- package/dist/esm/u-jump-to-unidy.entry.js +22 -43
- package/dist/esm/u-jump-to-unidy.entry.js.map +1 -1
- package/dist/esm/u-logout-button.u-signed-in.entry.js.map +1 -1
- package/dist/esm/u-logout-button_2.entry.js +15 -22
- package/dist/esm/u-magic-code-field.entry.js +8 -9
- package/dist/esm/u-magic-code-field.entry.js.map +1 -1
- package/dist/esm/u-missing-field.entry.js +6 -5
- package/dist/esm/u-missing-field.entry.js.map +1 -1
- package/dist/esm/u-missing-fields-submit-button.entry.js +16 -14
- package/dist/esm/u-missing-fields-submit-button.entry.js.map +1 -1
- package/dist/esm/u-newsletter-checkbox.entry.js +11 -12
- package/dist/esm/u-newsletter-checkbox.entry.js.map +1 -1
- package/dist/esm/u-newsletter-consent-checkbox.entry.js +4 -4
- package/dist/esm/u-newsletter-logout-button.entry.js +15 -20
- package/dist/esm/u-newsletter-logout-button.entry.js.map +1 -1
- package/dist/esm/u-newsletter-preference-checkbox.entry.js +11 -12
- package/dist/esm/u-newsletter-preference-checkbox.entry.js.map +1 -1
- package/dist/esm/u-newsletter-resend-doi-button.entry.js +10 -11
- package/dist/esm/u-newsletter-resend-doi-button.entry.js.map +1 -1
- package/dist/esm/u-newsletter-root.entry.js +42 -19
- package/dist/esm/u-newsletter-root.entry.js.map +1 -1
- package/dist/esm/u-newsletter-toggle-subscription-button.entry.js +11 -12
- package/dist/esm/u-newsletter-toggle-subscription-button.entry.js.map +1 -1
- package/dist/esm/u-pagination-button.entry.js +4 -4
- package/dist/esm/u-pagination-button.entry.js.map +1 -1
- package/dist/esm/u-pagination-page.entry.js +4 -4
- package/dist/esm/u-pagination-page.entry.js.map +1 -1
- package/dist/esm/u-passkey.entry.js +8 -9
- package/dist/esm/u-passkey.entry.js.map +1 -1
- package/dist/esm/u-password-field.entry.js +5 -5
- package/dist/esm/u-profile.u-submit-button.entry.js.map +1 -1
- package/dist/esm/u-profile_2.entry.js +31 -33
- package/dist/esm/u-registration-button.entry.js +5 -5
- package/dist/esm/u-reset-password-button.entry.js +12 -15
- package/dist/esm/u-reset-password-button.entry.js.map +1 -1
- package/dist/esm/u-send-magic-code-button.entry.js +8 -9
- package/dist/esm/u-send-magic-code-button.entry.js.map +1 -1
- package/dist/esm/u-signin-root.entry.js +6 -8
- package/dist/esm/u-signin-root.entry.js.map +1 -1
- package/dist/esm/u-signin-step.entry.js +17 -21
- package/dist/esm/u-signin-step.entry.js.map +1 -1
- package/dist/esm/u-social-login-button.entry.js +16 -15
- package/dist/esm/u-social-login-button.entry.js.map +1 -1
- package/dist/esm/u-spinner.entry.js +3 -3
- package/dist/esm/u-spinner.entry.js.map +1 -1
- package/dist/esm/u-ticketable-export.entry.js +74 -0
- package/dist/esm/u-ticketable-export.entry.js.map +1 -0
- package/dist/esm/u-ticketable-list-D2p21JjR.js +3981 -0
- package/dist/esm/u-ticketable-list-D2p21JjR.js.map +1 -0
- package/dist/esm/u-ticketable-list.entry.js +10 -6121
- package/dist/esm/u-ticketable-list.entry.js.map +1 -1
- package/dist/esm/{unidy-store-Bg7IaIMd.js → unidy-store-B5Bf4Vit.js} +3 -3
- package/dist/esm/{unidy-store-Bg7IaIMd.js.map → unidy-store-B5Bf4Vit.js.map} +1 -1
- package/dist/sdk/index.esm.js +1 -1
- package/dist/sdk/index.esm.js.map +1 -1
- package/dist/sdk/locales/de.json +16 -0
- package/dist/sdk/locales/en.json +16 -0
- package/dist/sdk/locales/fr.json +16 -0
- package/dist/sdk/locales/it.json +16 -0
- package/dist/sdk/locales/nl_be.json +16 -0
- package/dist/sdk/locales/ro.json +16 -0
- package/dist/sdk/p-02dce5da.entry.js +2 -0
- package/dist/sdk/p-02dce5da.entry.js.map +1 -0
- package/dist/sdk/p-043c7643.entry.js +2 -0
- package/dist/sdk/p-043c7643.entry.js.map +1 -0
- package/dist/sdk/p-18c17747.entry.js +2 -0
- package/dist/sdk/p-18c17747.entry.js.map +1 -0
- package/dist/sdk/p-1a1c1af0.entry.js +2 -0
- package/dist/sdk/p-1a1c1af0.entry.js.map +1 -0
- package/dist/sdk/p-271781c7.entry.js +2 -0
- package/dist/sdk/{p-1a8973a6.entry.js.map → p-271781c7.entry.js.map} +1 -1
- package/dist/sdk/p-29473a55.entry.js +2 -0
- package/dist/sdk/p-29473a55.entry.js.map +1 -0
- package/dist/sdk/p-2a25d62e.entry.js +2 -0
- package/dist/sdk/p-2a25d62e.entry.js.map +1 -0
- package/dist/sdk/{p-C8lRzJEX.js → p-2bKltz_F.js} +2 -2
- package/dist/sdk/{p-C8lRzJEX.js.map → p-2bKltz_F.js.map} +1 -1
- package/dist/sdk/p-2cc3a00d.entry.js +2 -0
- package/dist/sdk/p-2cc3a00d.entry.js.map +1 -0
- package/dist/sdk/p-2f49e0cb.entry.js +2 -0
- package/dist/sdk/p-2f49e0cb.entry.js.map +1 -0
- package/dist/sdk/p-34f5d201.entry.js +2 -0
- package/dist/sdk/p-34f5d201.entry.js.map +1 -0
- package/dist/sdk/p-52c4bdd9.entry.js +2 -0
- package/dist/sdk/p-52c4bdd9.entry.js.map +1 -0
- package/dist/sdk/p-585a0efa.entry.js +2 -0
- package/dist/sdk/p-585a0efa.entry.js.map +1 -0
- package/dist/sdk/p-60675019.entry.js +2 -0
- package/dist/sdk/p-60675019.entry.js.map +1 -0
- package/dist/sdk/p-79ef9a70.entry.js +2 -0
- package/dist/sdk/p-79ef9a70.entry.js.map +1 -0
- package/dist/sdk/p-7d88e21c.entry.js +2 -0
- package/dist/sdk/p-7d88e21c.entry.js.map +1 -0
- package/dist/sdk/p-7eaf3468.entry.js +2 -0
- package/dist/sdk/p-7eaf3468.entry.js.map +1 -0
- package/dist/sdk/{p-88beb872.entry.js → p-8412762c.entry.js} +2 -2
- package/dist/sdk/p-8ea70c08.entry.js +2 -0
- package/dist/sdk/p-8ea70c08.entry.js.map +1 -0
- package/dist/sdk/p-946cdb0a.entry.js +2 -0
- package/dist/sdk/p-946cdb0a.entry.js.map +1 -0
- package/dist/sdk/p-94bb0217.entry.js +2 -0
- package/dist/sdk/p-94bb0217.entry.js.map +1 -0
- package/dist/sdk/{p-bcca06f1.entry.js → p-96860b09.entry.js} +2 -2
- package/dist/sdk/p-B1A6Nu24.js +2 -0
- package/dist/sdk/p-B1A6Nu24.js.map +1 -0
- package/dist/sdk/p-B85MJLTf.js +2 -0
- package/dist/sdk/p-B85MJLTf.js.map +1 -0
- package/dist/sdk/p-B8N6Bwsa.js +2 -0
- package/dist/sdk/{p-DCG3L43i.js.map → p-B8N6Bwsa.js.map} +1 -1
- package/dist/sdk/p-Ba5szISo.js +2 -0
- package/dist/sdk/p-Ba5szISo.js.map +1 -0
- package/dist/sdk/p-BsJDptgj.js +14 -0
- package/dist/sdk/p-BsJDptgj.js.map +1 -0
- package/dist/sdk/{p-bpXpOZY_.js → p-C0Mo15qt.js} +2 -2
- package/dist/sdk/{p-bpXpOZY_.js.map → p-C0Mo15qt.js.map} +1 -1
- package/dist/sdk/p-C10MAuCE.js +2 -0
- package/dist/sdk/p-C10MAuCE.js.map +1 -0
- package/dist/sdk/p-CTy6pQSg.js +2 -0
- package/dist/sdk/p-CTy6pQSg.js.map +1 -0
- package/dist/sdk/p-CW6kGAuQ.js +2 -0
- package/dist/sdk/p-CW6kGAuQ.js.map +1 -0
- package/dist/sdk/{p-DdMKVWx8.js → p-CbSP8My1.js} +2 -2
- package/dist/sdk/{p-DdMKVWx8.js.map → p-CbSP8My1.js.map} +1 -1
- package/dist/sdk/p-CbzzI4uW.js +2 -0
- package/dist/sdk/p-CbzzI4uW.js.map +1 -0
- package/dist/sdk/p-CgT6fZjb.js +2 -0
- package/dist/sdk/p-CgT6fZjb.js.map +1 -0
- package/dist/sdk/p-CuHZ3IkE.js +2 -0
- package/dist/sdk/p-CuHZ3IkE.js.map +1 -0
- package/dist/sdk/p-Cysk_vik.js +2 -0
- package/dist/sdk/p-Cysk_vik.js.map +1 -0
- package/dist/sdk/p-D0ut3waq.js +2 -0
- package/dist/sdk/p-D0ut3waq.js.map +1 -0
- package/dist/sdk/{p-BigbTrKk.js → p-D2Rf-QGm.js} +2 -2
- package/dist/sdk/{p-BigbTrKk.js.map → p-D2Rf-QGm.js.map} +1 -1
- package/dist/sdk/{p-6rqGeAfT.js → p-D9yFO_ID.js} +2 -2
- package/dist/sdk/{p-6rqGeAfT.js.map → p-D9yFO_ID.js.map} +1 -1
- package/dist/sdk/p-DD_5soRi.js +2 -0
- package/dist/sdk/p-DD_5soRi.js.map +1 -0
- package/dist/sdk/p-DHuvvagO.js +2 -0
- package/dist/sdk/p-DHuvvagO.js.map +1 -0
- package/dist/sdk/p-DSMkJu9G.js +2 -0
- package/dist/sdk/p-DSMkJu9G.js.map +1 -0
- package/dist/sdk/p-DcirMfca.js +2 -0
- package/dist/sdk/p-DcirMfca.js.map +1 -0
- package/dist/sdk/p-J0cv5IOA.js +2 -0
- package/dist/sdk/p-J0cv5IOA.js.map +1 -0
- package/dist/sdk/p-_5evboqW.js +2 -0
- package/dist/sdk/{p-DSktNM_k.js.map → p-_5evboqW.js.map} +1 -1
- package/dist/sdk/{p-7ee2f2ab.entry.js → p-ac3a6bbf.entry.js} +2 -2
- package/dist/sdk/p-b498bcdd.entry.js +2 -0
- package/dist/sdk/p-b498bcdd.entry.js.map +1 -0
- package/dist/sdk/p-b5dd5b4c.entry.js +2 -0
- package/dist/sdk/p-b5dd5b4c.entry.js.map +1 -0
- package/dist/sdk/{p-6b061b18.entry.js → p-b99588a8.entry.js} +2 -2
- package/dist/sdk/p-bf9c27a8.entry.js +2 -0
- package/dist/sdk/p-bf9c27a8.entry.js.map +1 -0
- package/dist/sdk/p-c10d9b8e.entry.js +2 -0
- package/dist/sdk/p-c10d9b8e.entry.js.map +1 -0
- package/dist/sdk/{p-10e20afd.entry.js → p-c2634439.entry.js} +2 -2
- package/dist/sdk/p-d6777395.entry.js +2 -0
- package/dist/sdk/p-d6777395.entry.js.map +1 -0
- package/dist/sdk/p-dbfe7b29.entry.js +2 -0
- package/dist/sdk/p-dbfe7b29.entry.js.map +1 -0
- package/dist/sdk/p-def4e874.entry.js +2 -0
- package/dist/sdk/p-def4e874.entry.js.map +1 -0
- package/dist/sdk/p-e872a012.entry.js +2 -0
- package/dist/sdk/p-e872a012.entry.js.map +1 -0
- package/dist/sdk/p-eaaf3989.entry.js +2 -0
- package/dist/sdk/p-eaaf3989.entry.js.map +1 -0
- package/dist/sdk/p-fd46b459.entry.js +2 -0
- package/dist/sdk/{p-830778eb.entry.js.map → p-fd46b459.entry.js.map} +1 -1
- package/dist/sdk/sdk.esm.js +1 -1
- package/dist/sdk/u-conditional-render.entry.esm.js.map +1 -1
- package/dist/sdk/u-config.entry.esm.js.map +1 -1
- package/dist/sdk/u-error-message.entry.esm.js.map +1 -1
- package/dist/sdk/u-field.u-raw-field.entry.esm.js.map +1 -1
- package/dist/sdk/u-jump-to-service.entry.esm.js.map +1 -1
- package/dist/sdk/u-jump-to-unidy.entry.esm.js.map +1 -1
- package/dist/sdk/u-logout-button.u-signed-in.entry.esm.js.map +1 -1
- package/dist/sdk/u-magic-code-field.entry.esm.js.map +1 -1
- package/dist/sdk/u-missing-field.entry.esm.js.map +1 -1
- package/dist/sdk/u-missing-fields-submit-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-checkbox.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-logout-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-preference-checkbox.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-resend-doi-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-root.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-toggle-subscription-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-pagination-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-pagination-page.entry.esm.js.map +1 -1
- package/dist/sdk/u-passkey.entry.esm.js.map +1 -1
- package/dist/sdk/u-profile.u-submit-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-reset-password-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-send-magic-code-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-signin-root.entry.esm.js.map +1 -1
- package/dist/sdk/u-signin-step.entry.esm.js.map +1 -1
- package/dist/sdk/u-social-login-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-spinner.entry.esm.js.map +1 -1
- package/dist/sdk/u-ticketable-export.entry.esm.js.map +1 -0
- package/dist/sdk/u-ticketable-list.entry.esm.js.map +1 -1
- package/dist/types/api/client.d.ts +1 -1
- package/dist/types/api/index.d.ts +4 -4
- package/dist/types/api/standalone.d.ts +9 -9
- package/dist/types/auth/api/auth.d.ts +2 -3
- package/dist/types/auth/api/schemas.d.ts +19 -19
- package/dist/types/auth/auth-helpers.d.ts +1 -0
- package/dist/types/auth/components/jump-to-service/jump-to-service.d.ts +13 -5
- package/dist/types/auth/components/jump-to-unidy/jump-to-unidy.d.ts +13 -9
- package/dist/types/auth/components/logout-button/logout-button.d.ts +13 -4
- package/dist/types/auth/components/missing-field/missing-field.d.ts +1 -0
- package/dist/types/auth/components/missing-fields-submit-button/missing-fields-submit-button.d.ts +14 -2
- package/dist/types/auth/components/reset-pass-button/reset-pass-button.d.ts +13 -4
- package/dist/types/auth/components/social-logins/social-login-button.d.ts +11 -7
- package/dist/types/components.d.ts +73 -0
- package/dist/types/logger.d.ts +0 -34
- package/dist/types/newsletter/components/logout-button/logout-button.d.ts +13 -4
- package/dist/types/newsletter/components/newsletter-root/newsletter-root.d.ts +16 -2
- package/dist/types/newsletter/newsletter-helpers.d.ts +8 -2
- package/dist/types/newsletter/store/newsletter-store.d.ts +8 -1
- package/dist/types/profile/api/profile.d.ts +2 -2
- package/dist/types/profile/api/schemas.d.ts +21 -21
- package/dist/types/profile/components/raw-field/raw-field.d.ts +14 -2
- package/dist/types/shared/base/component.d.ts +46 -0
- package/dist/types/shared/base/has-slot-content.d.ts +10 -0
- package/dist/types/shared/component-utils.d.ts +20 -12
- package/dist/types/shared/components/conditional-render/conditional-render.d.ts +7 -2
- package/dist/types/shared/components/config/config.d.ts +7 -2
- package/dist/types/shared/components/error-message/error-message.d.ts +14 -2
- package/dist/types/shared/components/submit-button/submit-button.d.ts +13 -4
- package/dist/types/shared/context-utils.d.ts +73 -0
- package/dist/types/shared/utils/redirect-with-token.d.ts +21 -0
- package/dist/types/shared/utils/url-utils.d.ts +16 -0
- package/dist/types/ticketable/api/schemas.d.ts +16 -2
- package/dist/types/ticketable/api/subscriptions.d.ts +8 -3
- package/dist/types/ticketable/api/tickets.d.ts +8 -3
- package/dist/types/ticketable/components/pagination/pagination-button.d.ts +8 -4
- package/dist/types/ticketable/components/pagination/pagination-page.d.ts +8 -4
- package/dist/types/ticketable/components/ticketable-export/ticketable-export.d.ts +24 -0
- package/dist/types/ticketable/components/ticketable-list/ticketable-list.d.ts +10 -4
- package/dist/types/ticketable/index.d.ts +1 -0
- package/package.json +6 -2
- package/readme.md +248 -27
- package/dist/cjs/app-globals-hdkLqF51.js +0 -10
- package/dist/cjs/app-globals-hdkLqF51.js.map +0 -1
- package/dist/cjs/component-utils-bu3SY4dE.js +0 -42
- package/dist/cjs/component-utils-bu3SY4dE.js.map +0 -1
- package/dist/cjs/index-B325yXfO.js.map +0 -1
- package/dist/cjs/index-BzPYBLYC.js.map +0 -1
- package/dist/cjs/newsletter-helpers-hdDC5X-V.js.map +0 -1
- package/dist/cjs/newsletter-store-CupsLgO9.js.map +0 -1
- package/dist/cjs/pagination-store-zo48QpTm.js +0 -16
- package/dist/cjs/pagination-store-zo48QpTm.js.map +0 -1
- package/dist/components/pagination-store.js +0 -14
- package/dist/components/pagination-store.js.map +0 -1
- package/dist/esm/app-globals-iHhGdwBB.js +0 -8
- package/dist/esm/app-globals-iHhGdwBB.js.map +0 -1
- package/dist/esm/component-utils-BGq0leDV.js +0 -39
- package/dist/esm/component-utils-BGq0leDV.js.map +0 -1
- package/dist/esm/index-BVlbCQEX.js.map +0 -1
- package/dist/esm/index-FTKB5a1d.js.map +0 -1
- package/dist/esm/newsletter-helpers-fCpxzovf.js.map +0 -1
- package/dist/esm/newsletter-store-BB618FgS.js.map +0 -1
- package/dist/esm/pagination-store-DxmcQH8R.js +0 -14
- package/dist/esm/pagination-store-DxmcQH8R.js.map +0 -1
- package/dist/sdk/p-1a8973a6.entry.js +0 -2
- package/dist/sdk/p-35ad60ab.entry.js +0 -2
- package/dist/sdk/p-35ad60ab.entry.js.map +0 -1
- package/dist/sdk/p-3f352f38.entry.js +0 -2
- package/dist/sdk/p-3f352f38.entry.js.map +0 -1
- package/dist/sdk/p-468aaf62.entry.js +0 -2
- package/dist/sdk/p-468aaf62.entry.js.map +0 -1
- package/dist/sdk/p-4e2e6a13.entry.js +0 -2
- package/dist/sdk/p-4e2e6a13.entry.js.map +0 -1
- package/dist/sdk/p-57c8dc68.entry.js +0 -2
- package/dist/sdk/p-57c8dc68.entry.js.map +0 -1
- package/dist/sdk/p-594aec0c.entry.js +0 -2
- package/dist/sdk/p-594aec0c.entry.js.map +0 -1
- package/dist/sdk/p-60c8be64.entry.js +0 -2
- package/dist/sdk/p-60c8be64.entry.js.map +0 -1
- package/dist/sdk/p-760718d3.entry.js +0 -2
- package/dist/sdk/p-760718d3.entry.js.map +0 -1
- package/dist/sdk/p-77f541f3.entry.js +0 -2
- package/dist/sdk/p-77f541f3.entry.js.map +0 -1
- package/dist/sdk/p-830778eb.entry.js +0 -2
- package/dist/sdk/p-8839648e.entry.js +0 -2
- package/dist/sdk/p-8839648e.entry.js.map +0 -1
- package/dist/sdk/p-B6MYe-dh.js +0 -2
- package/dist/sdk/p-B6MYe-dh.js.map +0 -1
- package/dist/sdk/p-BGq0leDV.js +0 -2
- package/dist/sdk/p-BGq0leDV.js.map +0 -1
- package/dist/sdk/p-C_UZBwdm.js +0 -2
- package/dist/sdk/p-C_UZBwdm.js.map +0 -1
- package/dist/sdk/p-CbazSxaZ.js +0 -2
- package/dist/sdk/p-CbazSxaZ.js.map +0 -1
- package/dist/sdk/p-DCG3L43i.js +0 -2
- package/dist/sdk/p-DEUPZOH-.js +0 -2
- package/dist/sdk/p-DEUPZOH-.js.map +0 -1
- package/dist/sdk/p-DSktNM_k.js +0 -2
- package/dist/sdk/p-FTKB5a1d.js +0 -14
- package/dist/sdk/p-FTKB5a1d.js.map +0 -1
- package/dist/sdk/p-a7ffcff9.entry.js +0 -2
- package/dist/sdk/p-a7ffcff9.entry.js.map +0 -1
- package/dist/sdk/p-acaba1d5.entry.js +0 -2
- package/dist/sdk/p-acaba1d5.entry.js.map +0 -1
- package/dist/sdk/p-ae47a7a3.entry.js +0 -2
- package/dist/sdk/p-ae47a7a3.entry.js.map +0 -1
- package/dist/sdk/p-aec580e4.entry.js +0 -2
- package/dist/sdk/p-aec580e4.entry.js.map +0 -1
- package/dist/sdk/p-b63438ff.entry.js +0 -2
- package/dist/sdk/p-b63438ff.entry.js.map +0 -1
- package/dist/sdk/p-baaaa7f5.entry.js +0 -2
- package/dist/sdk/p-baaaa7f5.entry.js.map +0 -1
- package/dist/sdk/p-bba2da84.entry.js +0 -2
- package/dist/sdk/p-bba2da84.entry.js.map +0 -1
- package/dist/sdk/p-bc47f42b.entry.js +0 -2
- package/dist/sdk/p-bc47f42b.entry.js.map +0 -1
- package/dist/sdk/p-bd51e26f.entry.js +0 -2
- package/dist/sdk/p-bd51e26f.entry.js.map +0 -1
- package/dist/sdk/p-c3552f75.entry.js +0 -2
- package/dist/sdk/p-c3552f75.entry.js.map +0 -1
- package/dist/sdk/p-d9900482.entry.js +0 -2
- package/dist/sdk/p-d9900482.entry.js.map +0 -1
- package/dist/sdk/p-e6796c38.entry.js +0 -2
- package/dist/sdk/p-e6796c38.entry.js.map +0 -1
- package/dist/sdk/p-f272eb38.entry.js +0 -2
- package/dist/sdk/p-f272eb38.entry.js.map +0 -1
- package/dist/sdk/p-f4a47ef8.entry.js +0 -2
- package/dist/sdk/p-f4a47ef8.entry.js.map +0 -1
- package/dist/sdk/p-f608e64a.entry.js +0 -2
- package/dist/sdk/p-f608e64a.entry.js.map +0 -1
- package/dist/sdk/p-f762ac70.entry.js +0 -2
- package/dist/sdk/p-f762ac70.entry.js.map +0 -1
- package/dist/sdk/p-l6NinBiD.js +0 -2
- package/dist/sdk/p-l6NinBiD.js.map +0 -1
- /package/dist/sdk/{p-88beb872.entry.js.map → p-8412762c.entry.js.map} +0 -0
- /package/dist/sdk/{p-bcca06f1.entry.js.map → p-96860b09.entry.js.map} +0 -0
- /package/dist/sdk/{p-7ee2f2ab.entry.js.map → p-ac3a6bbf.entry.js.map} +0 -0
- /package/dist/sdk/{p-6b061b18.entry.js.map → p-b99588a8.entry.js.map} +0 -0
- /package/dist/sdk/{p-10e20afd.entry.js.map → p-c2634439.entry.js.map} +0 -0
|
@@ -1,166 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var index = require('./index-
|
|
5
|
-
var
|
|
6
|
-
var i18n = require('./i18n-
|
|
7
|
-
var authStore = require('./auth-store-
|
|
8
|
-
var
|
|
9
|
-
var flashStore = require('./flash-store-gbSYhPAV.js');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Base API client with shared functionality for both browser and standalone environments.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Abstract base class for API clients.
|
|
16
|
-
* Provides shared functionality for making HTTP requests.
|
|
17
|
-
*/
|
|
18
|
-
class BaseApiClient {
|
|
19
|
-
/**
|
|
20
|
-
* Error messages that indicate a connection failure rather than a server error.
|
|
21
|
-
* Grouped by source/environment.
|
|
22
|
-
*/
|
|
23
|
-
static CONNECTION_ERROR_MESSAGES = [
|
|
24
|
-
// Browser fetch API errors
|
|
25
|
-
"Failed to fetch", // Generic browser fetch failure (Chrome)
|
|
26
|
-
"NetworkError", // Firefox network error
|
|
27
|
-
"Load failed", // Safari network error
|
|
28
|
-
"The network connection was lost", // Safari connection lost
|
|
29
|
-
// Chromium/V8 error codes (used by Node.js and Chrome)
|
|
30
|
-
"ERR_CONNECTION_REFUSED", // Server not accepting connections
|
|
31
|
-
"ERR_NETWORK", // General network error
|
|
32
|
-
"ERR_INTERNET_DISCONNECTED", // No internet connection
|
|
33
|
-
// Node.js system error codes
|
|
34
|
-
"ECONNREFUSED", // Connection refused by server
|
|
35
|
-
"ENOTFOUND", // DNS lookup failed
|
|
36
|
-
"EAI_AGAIN", // Temporary DNS failure
|
|
37
|
-
];
|
|
38
|
-
onConnectionChange;
|
|
39
|
-
baseUrl;
|
|
40
|
-
api_key;
|
|
41
|
-
constructor(config) {
|
|
42
|
-
this.baseUrl = config.baseUrl;
|
|
43
|
-
this.api_key = config.apiKey;
|
|
44
|
-
this.onConnectionChange = config.onConnectionChange;
|
|
45
|
-
}
|
|
46
|
-
isConnectionError(error) {
|
|
47
|
-
if (error instanceof Error) {
|
|
48
|
-
return BaseApiClient.CONNECTION_ERROR_MESSAGES.some((msg) => error.message.includes(msg));
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
setConnectionStatus(isConnected) {
|
|
53
|
-
this.onConnectionChange?.(isConnected);
|
|
54
|
-
}
|
|
55
|
-
baseHeaders() {
|
|
56
|
-
const h = new Headers();
|
|
57
|
-
h.set("Content-Type", "application/json");
|
|
58
|
-
h.set("Accept", "application/json");
|
|
59
|
-
h.set("Authorization", `Bearer ${this.api_key}`);
|
|
60
|
-
return h;
|
|
61
|
-
}
|
|
62
|
-
mergeHeaders(base, extra) {
|
|
63
|
-
const out = new Headers(base);
|
|
64
|
-
if (extra) {
|
|
65
|
-
new Headers(extra).forEach((v, k) => {
|
|
66
|
-
out.set(k, v);
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
return out;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Builds a query string from params, filtering out undefined/null values.
|
|
73
|
-
*/
|
|
74
|
-
buildQueryString(params) {
|
|
75
|
-
if (!params)
|
|
76
|
-
return "";
|
|
77
|
-
const filtered = Object.entries(params)
|
|
78
|
-
.filter(([_, v]) => v !== undefined && v !== null)
|
|
79
|
-
.map(([k, v]) => [k, String(v)]);
|
|
80
|
-
if (filtered.length === 0)
|
|
81
|
-
return "";
|
|
82
|
-
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
83
|
-
}
|
|
84
|
-
async request(method, endpoint, body, headers) {
|
|
85
|
-
let res = null;
|
|
86
|
-
try {
|
|
87
|
-
res = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
88
|
-
method,
|
|
89
|
-
...this.getRequestOptions(),
|
|
90
|
-
headers: this.mergeHeaders(this.baseHeaders(), headers),
|
|
91
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
92
|
-
});
|
|
93
|
-
let data;
|
|
94
|
-
try {
|
|
95
|
-
data = await res.json();
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
data = undefined;
|
|
99
|
-
}
|
|
100
|
-
this.setConnectionStatus(true);
|
|
101
|
-
return {
|
|
102
|
-
data,
|
|
103
|
-
status: res.status,
|
|
104
|
-
headers: res.headers,
|
|
105
|
-
success: res.ok,
|
|
106
|
-
connectionError: false,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
const connectionFailed = this.isConnectionError(error);
|
|
111
|
-
if (connectionFailed) {
|
|
112
|
-
this.setConnectionStatus(false);
|
|
113
|
-
this.handleConnectionError(error, endpoint, method);
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
status: res?.status ?? (connectionFailed ? 0 : 500),
|
|
117
|
-
error: error instanceof Error ? error.message : String(error),
|
|
118
|
-
headers: res?.headers ?? new Headers(),
|
|
119
|
-
success: false,
|
|
120
|
-
data: undefined,
|
|
121
|
-
connectionError: connectionFailed,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
async get(endpoint, headers, params) {
|
|
126
|
-
const queryString = this.buildQueryString(params);
|
|
127
|
-
return this.request("GET", `${endpoint}${queryString}`, undefined, headers);
|
|
128
|
-
}
|
|
129
|
-
async post(endpoint, body, headers) {
|
|
130
|
-
return this.request("POST", endpoint, body, headers);
|
|
131
|
-
}
|
|
132
|
-
async patch(endpoint, body, headers) {
|
|
133
|
-
return this.request("PATCH", endpoint, body, headers);
|
|
134
|
-
}
|
|
135
|
-
async delete(endpoint, headers) {
|
|
136
|
-
return this.request("DELETE", endpoint, undefined, headers);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Browser-specific API client with CORS mode and Sentry error reporting.
|
|
142
|
-
*/
|
|
143
|
-
class ApiClient extends BaseApiClient {
|
|
144
|
-
constructor(baseUrl, apiKey, onConnectionChange) {
|
|
145
|
-
super({ baseUrl, apiKey, onConnectionChange });
|
|
146
|
-
}
|
|
147
|
-
setConnectionStatus(isConnected) {
|
|
148
|
-
super.setConnectionStatus(isConnected);
|
|
149
|
-
unidyStore.unidyState.backendConnected = isConnected;
|
|
150
|
-
}
|
|
151
|
-
getRequestOptions() {
|
|
152
|
-
return {
|
|
153
|
-
mode: "cors",
|
|
154
|
-
credentials: "include",
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
handleConnectionError(error, endpoint, method) {
|
|
158
|
-
index.captureException(error, {
|
|
159
|
-
tags: { error_type: "connection_error" },
|
|
160
|
-
extra: { endpoint, method },
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
3
|
+
var profileStore = require('./profile-store-CQEQhPQD.js');
|
|
4
|
+
var index = require('./index-2Fz3r5o0.js');
|
|
5
|
+
var unidyStore = require('./unidy-store-Bvnl24i9.js');
|
|
6
|
+
var i18n = require('./i18n-ClWrNmGh.js');
|
|
7
|
+
var authStore = require('./auth-store-0vv3uOib.js');
|
|
8
|
+
var flashStore = require('./flash-store-CR6Umh1O.js');
|
|
164
9
|
|
|
165
10
|
/** A special constant with type `never` */
|
|
166
11
|
function $constructor(name, initializer, params) {
|
|
@@ -5150,7 +4995,7 @@ const BaseFieldDataSchema = object({
|
|
|
5150
4995
|
label: string(),
|
|
5151
4996
|
attr_name: string(),
|
|
5152
4997
|
locked: boolean().optional(),
|
|
5153
|
-
locked_text: string().
|
|
4998
|
+
locked_text: string().nullish(),
|
|
5154
4999
|
})
|
|
5155
5000
|
.strict();
|
|
5156
5001
|
// Select option schema
|
|
@@ -5364,7 +5209,7 @@ const ErrorSchema = BaseErrorSchema;
|
|
|
5364
5209
|
// Magic code response
|
|
5365
5210
|
const SendMagicCodeResponseSchema = object({
|
|
5366
5211
|
enable_resend_after: number(),
|
|
5367
|
-
sid: string().
|
|
5212
|
+
sid: string().nullish(),
|
|
5368
5213
|
login_options: object({
|
|
5369
5214
|
magic_link: boolean(),
|
|
5370
5215
|
})
|
|
@@ -5377,7 +5222,7 @@ const SendMagicCodeErrorSchema = BaseErrorSchema.extend({
|
|
|
5377
5222
|
// JWT token response
|
|
5378
5223
|
const TokenResponseSchema = object({
|
|
5379
5224
|
jwt: string(),
|
|
5380
|
-
sid: string().
|
|
5225
|
+
sid: string().nullish(),
|
|
5381
5226
|
});
|
|
5382
5227
|
// Missing required fields response extends base error with specific error_identifier
|
|
5383
5228
|
const RequiredFieldsResponseSchema = object({
|
|
@@ -5386,7 +5231,7 @@ const RequiredFieldsResponseSchema = object({
|
|
|
5386
5231
|
fields: UserProfileSchema.omit({ custom_attributes: true }).partial().extend({
|
|
5387
5232
|
custom_attributes: UserProfileSchema.shape.custom_attributes?.optional(),
|
|
5388
5233
|
}),
|
|
5389
|
-
sid: string().
|
|
5234
|
+
sid: string().nullish(),
|
|
5390
5235
|
}),
|
|
5391
5236
|
})
|
|
5392
5237
|
.transform(({ error_identifier, meta }) => ({
|
|
@@ -5428,8 +5273,8 @@ const JumpToUnidyErrorSchema = object({
|
|
|
5428
5273
|
});
|
|
5429
5274
|
const JumpToServiceRequestSchema = object({
|
|
5430
5275
|
email: string(),
|
|
5431
|
-
redirect_uri: string().
|
|
5432
|
-
scopes: array(string()).
|
|
5276
|
+
redirect_uri: string().nullish(),
|
|
5277
|
+
scopes: array(string()).nullish(),
|
|
5433
5278
|
skip_oauth_authorization: boolean().optional(),
|
|
5434
5279
|
});
|
|
5435
5280
|
const JumpToUnidyRequestSchema = object({
|
|
@@ -5700,672 +5545,158 @@ class AuthService extends BaseService {
|
|
|
5700
5545
|
}
|
|
5701
5546
|
}
|
|
5702
5547
|
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
});
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
first_name: string().nullable(),
|
|
5729
|
-
last_name: string().nullable(),
|
|
5730
|
-
salutation: SalutationEnum.nullable(),
|
|
5731
|
-
phone_number: string().nullable(),
|
|
5732
|
-
date_of_birth: string().nullable(),
|
|
5733
|
-
company_name: string().nullable(),
|
|
5734
|
-
address_line_1: string().nullable(),
|
|
5735
|
-
address_line_2: string().nullable(),
|
|
5736
|
-
city: string().nullable(),
|
|
5737
|
-
postal_code: string().nullable(),
|
|
5738
|
-
country_code: string().nullable(),
|
|
5739
|
-
preferred_language: string().nullable(),
|
|
5740
|
-
custom_attributes: record(string(), unknown()).nullable(),
|
|
5741
|
-
})
|
|
5742
|
-
.partial();
|
|
5743
|
-
// Create subscriptions payload
|
|
5744
|
-
const CreateSubscriptionsPayloadSchema = object({
|
|
5745
|
-
email: string(),
|
|
5746
|
-
additional_fields: optional(AdditionalFieldsSchema),
|
|
5747
|
-
newsletter_subscriptions: array(object({
|
|
5748
|
-
newsletter_internal_name: string(),
|
|
5749
|
-
preference_identifiers: optional(array(string())),
|
|
5750
|
-
})),
|
|
5751
|
-
redirect_to_after_confirmation: optional(string()),
|
|
5752
|
-
});
|
|
5753
|
-
// Update subscription payload
|
|
5754
|
-
const UpdateSubscriptionPayloadSchema = object({
|
|
5755
|
-
preference_identifiers: array(string()),
|
|
5756
|
-
});
|
|
5757
|
-
// Login email payload
|
|
5758
|
-
const LoginEmailPayloadSchema = object({
|
|
5759
|
-
email: string(),
|
|
5760
|
-
redirect_uri: string(),
|
|
5761
|
-
});
|
|
5762
|
-
// Resend DOI payload
|
|
5763
|
-
const ResendDoiPayloadSchema = object({
|
|
5764
|
-
redirect_to_after_confirmation: string(),
|
|
5765
|
-
})
|
|
5766
|
-
.partial();
|
|
5767
|
-
// Preference schema
|
|
5768
|
-
const PreferenceSchema = object({
|
|
5769
|
-
id: number(),
|
|
5770
|
-
name: string(),
|
|
5771
|
-
description: string().nullable(),
|
|
5772
|
-
plugin_identifier: string().nullable(),
|
|
5773
|
-
position: number(),
|
|
5774
|
-
default: boolean(),
|
|
5775
|
-
hidden: boolean(),
|
|
5776
|
-
});
|
|
5777
|
-
// Preference group schema
|
|
5778
|
-
const PreferenceGroupSchema = object({
|
|
5779
|
-
id: number(),
|
|
5780
|
-
name: string(),
|
|
5781
|
-
position: number(),
|
|
5782
|
-
flat: boolean(),
|
|
5783
|
-
preferences: array(PreferenceSchema),
|
|
5784
|
-
});
|
|
5785
|
-
// Newsletter schema
|
|
5786
|
-
const NewsletterSchema = object({
|
|
5787
|
-
id: number(),
|
|
5788
|
-
internal_name: string(),
|
|
5789
|
-
default: boolean(),
|
|
5790
|
-
position: number(),
|
|
5791
|
-
opt_in_type: string(),
|
|
5792
|
-
title: string(),
|
|
5793
|
-
description: string().nullable(),
|
|
5794
|
-
created_at: string(),
|
|
5795
|
-
updated_at: string(),
|
|
5796
|
-
preference_groups: array(PreferenceGroupSchema),
|
|
5797
|
-
});
|
|
5798
|
-
// Newsletters list response
|
|
5799
|
-
const NewslettersResponseSchema = object({
|
|
5800
|
-
newsletters: array(NewsletterSchema),
|
|
5801
|
-
});
|
|
5802
|
-
// Delete subscription response
|
|
5803
|
-
const DeleteSubscriptionResponseSchema = object({
|
|
5804
|
-
new_preference_token: string(),
|
|
5805
|
-
})
|
|
5806
|
-
.nullable();
|
|
5807
|
-
// Generic newsletter error response (extends base error)
|
|
5808
|
-
const NewsletterErrorResponseSchema = BaseErrorSchema;
|
|
5809
|
-
|
|
5810
|
-
class NewsletterService extends BaseService {
|
|
5811
|
-
constructor(client, deps) {
|
|
5812
|
-
super(client, "NewsletterService", deps);
|
|
5548
|
+
class InvalidTokenError extends Error {
|
|
5549
|
+
}
|
|
5550
|
+
InvalidTokenError.prototype.name = "InvalidTokenError";
|
|
5551
|
+
function b64DecodeUnicode(str) {
|
|
5552
|
+
return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {
|
|
5553
|
+
let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
5554
|
+
if (code.length < 2) {
|
|
5555
|
+
code = "0" + code;
|
|
5556
|
+
}
|
|
5557
|
+
return "%" + code;
|
|
5558
|
+
}));
|
|
5559
|
+
}
|
|
5560
|
+
function base64UrlDecode(str) {
|
|
5561
|
+
let output = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
5562
|
+
switch (output.length % 4) {
|
|
5563
|
+
case 0:
|
|
5564
|
+
break;
|
|
5565
|
+
case 2:
|
|
5566
|
+
output += "==";
|
|
5567
|
+
break;
|
|
5568
|
+
case 3:
|
|
5569
|
+
output += "=";
|
|
5570
|
+
break;
|
|
5571
|
+
default:
|
|
5572
|
+
throw new Error("base64 string is not of the correct length");
|
|
5813
5573
|
}
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
return this.buildAuthHeaders({
|
|
5817
|
-
"X-ID-Token": idToken ?? undefined,
|
|
5818
|
-
"X-Preference-Token": options?.preferenceToken,
|
|
5819
|
-
});
|
|
5574
|
+
try {
|
|
5575
|
+
return b64DecodeUnicode(output);
|
|
5820
5576
|
}
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
*/
|
|
5824
|
-
async create(args) {
|
|
5825
|
-
const { payload, options } = args;
|
|
5826
|
-
const validatedPayload = CreateSubscriptionsPayloadSchema.safeParse(payload);
|
|
5827
|
-
if (!validatedPayload.success) {
|
|
5828
|
-
this.logger.error("Invalid payload for create", validatedPayload.error);
|
|
5829
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5830
|
-
}
|
|
5831
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5832
|
-
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription", payload, headers);
|
|
5833
|
-
return this.handleResponse(response, () => {
|
|
5834
|
-
if (!response.success) {
|
|
5835
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5836
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5837
|
-
switch (response.status) {
|
|
5838
|
-
case 401:
|
|
5839
|
-
return ["unauthorized", error];
|
|
5840
|
-
case 429:
|
|
5841
|
-
this.logger.warn("Rate limit exceeded");
|
|
5842
|
-
return ["rate_limit_exceeded", error];
|
|
5843
|
-
case 500:
|
|
5844
|
-
this.errorReporter.captureException(response);
|
|
5845
|
-
return ["server_error", error];
|
|
5846
|
-
default:
|
|
5847
|
-
return ["server_error", error];
|
|
5848
|
-
}
|
|
5849
|
-
}
|
|
5850
|
-
const data = CreateSubscriptionsResponseSchema.parse(response.data);
|
|
5851
|
-
if (data.errors.length > 0) {
|
|
5852
|
-
return ["newsletter_error", data];
|
|
5853
|
-
}
|
|
5854
|
-
return [null, data];
|
|
5855
|
-
});
|
|
5577
|
+
catch (err) {
|
|
5578
|
+
return atob(output);
|
|
5856
5579
|
}
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
const headers = await this.buildNewsletterAuthHeaders(args?.options);
|
|
5862
|
-
const response = await this.client.get("/api/sdk/v1/newsletters/newsletter_subscription", headers);
|
|
5863
|
-
return this.handleResponse(response, () => {
|
|
5864
|
-
if (!response.success) {
|
|
5865
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5866
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5867
|
-
if (response.status === 401) {
|
|
5868
|
-
return ["unauthorized", error];
|
|
5869
|
-
}
|
|
5870
|
-
return ["server_error", error];
|
|
5871
|
-
}
|
|
5872
|
-
const data = array(NewsletterSubscriptionSchema).parse(response.data);
|
|
5873
|
-
return [null, data];
|
|
5874
|
-
});
|
|
5580
|
+
}
|
|
5581
|
+
function jwtDecode(token, options) {
|
|
5582
|
+
if (typeof token !== "string") {
|
|
5583
|
+
throw new InvalidTokenError("Invalid token specified: must be a string");
|
|
5875
5584
|
}
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5882
|
-
const response = await this.client.get(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
5883
|
-
return this.handleResponse(response, () => {
|
|
5884
|
-
if (!response.success) {
|
|
5885
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5886
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5887
|
-
if (response.status === 401) {
|
|
5888
|
-
return ["unauthorized", error];
|
|
5889
|
-
}
|
|
5890
|
-
if (response.status === 404) {
|
|
5891
|
-
return ["not_found", error];
|
|
5892
|
-
}
|
|
5893
|
-
return ["server_error", error];
|
|
5894
|
-
}
|
|
5895
|
-
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
5896
|
-
return [null, data];
|
|
5897
|
-
});
|
|
5585
|
+
options || (options = {});
|
|
5586
|
+
const pos = options.header === true ? 0 : 1;
|
|
5587
|
+
const part = token.split(".")[pos];
|
|
5588
|
+
if (typeof part !== "string") {
|
|
5589
|
+
throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);
|
|
5898
5590
|
}
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
async update(args) {
|
|
5903
|
-
const { internalName, payload, options } = args;
|
|
5904
|
-
const validatedPayload = UpdateSubscriptionPayloadSchema.safeParse(payload);
|
|
5905
|
-
if (!validatedPayload.success) {
|
|
5906
|
-
this.logger.error("Invalid payload for update", validatedPayload.error);
|
|
5907
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5908
|
-
}
|
|
5909
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5910
|
-
const response = await this.client.patch(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, payload, headers);
|
|
5911
|
-
return this.handleResponse(response, () => {
|
|
5912
|
-
if (!response.success) {
|
|
5913
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5914
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5915
|
-
if (response.status === 401) {
|
|
5916
|
-
return ["unauthorized", error];
|
|
5917
|
-
}
|
|
5918
|
-
if (response.status === 404) {
|
|
5919
|
-
return ["not_found", error];
|
|
5920
|
-
}
|
|
5921
|
-
return ["server_error", error];
|
|
5922
|
-
}
|
|
5923
|
-
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
5924
|
-
return [null, data];
|
|
5925
|
-
});
|
|
5591
|
+
let decoded;
|
|
5592
|
+
try {
|
|
5593
|
+
decoded = base64UrlDecode(part);
|
|
5926
5594
|
}
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
*/
|
|
5930
|
-
async delete(args) {
|
|
5931
|
-
const { internalName, options } = args;
|
|
5932
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5933
|
-
const response = await this.client.delete(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
5934
|
-
return this.handleResponse(response, () => {
|
|
5935
|
-
if (!response.success) {
|
|
5936
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5937
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5938
|
-
if (response.status === 401) {
|
|
5939
|
-
return ["unauthorized", error];
|
|
5940
|
-
}
|
|
5941
|
-
if (response.status === 404) {
|
|
5942
|
-
return ["not_found", error];
|
|
5943
|
-
}
|
|
5944
|
-
if (response.status === 422) {
|
|
5945
|
-
return ["unprocessable_entity", error];
|
|
5946
|
-
}
|
|
5947
|
-
return ["server_error", error];
|
|
5948
|
-
}
|
|
5949
|
-
if (response.status === 204) {
|
|
5950
|
-
return [null, null];
|
|
5951
|
-
}
|
|
5952
|
-
const data = DeleteSubscriptionResponseSchema.parse(response.data);
|
|
5953
|
-
return [null, data];
|
|
5954
|
-
});
|
|
5595
|
+
catch (e) {
|
|
5596
|
+
throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);
|
|
5955
5597
|
}
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
*/
|
|
5959
|
-
async resendDoi(args) {
|
|
5960
|
-
const { internalName, payload, options } = args;
|
|
5961
|
-
const validatedPayload = ResendDoiPayloadSchema.safeParse(payload);
|
|
5962
|
-
if (!validatedPayload.success) {
|
|
5963
|
-
this.logger.error("Invalid payload for resendDoi", validatedPayload.error);
|
|
5964
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5965
|
-
}
|
|
5966
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5967
|
-
const response = await this.client.post(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription/resend_doi`, payload, headers);
|
|
5968
|
-
return this.handleResponse(response, () => {
|
|
5969
|
-
if (!response.success) {
|
|
5970
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5971
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5972
|
-
if (response.status === 401) {
|
|
5973
|
-
return ["unauthorized", error];
|
|
5974
|
-
}
|
|
5975
|
-
if (response.status === 404) {
|
|
5976
|
-
return ["not_found", error];
|
|
5977
|
-
}
|
|
5978
|
-
if (error.error_identifier === "already_confirmed") {
|
|
5979
|
-
return ["already_confirmed", error];
|
|
5980
|
-
}
|
|
5981
|
-
return ["server_error", error];
|
|
5982
|
-
}
|
|
5983
|
-
return [null, null];
|
|
5984
|
-
});
|
|
5598
|
+
try {
|
|
5599
|
+
return JSON.parse(decoded);
|
|
5985
5600
|
}
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
*/
|
|
5989
|
-
async sendLoginEmail(args) {
|
|
5990
|
-
const { payload } = args;
|
|
5991
|
-
const validatedPayload = LoginEmailPayloadSchema.safeParse(payload);
|
|
5992
|
-
if (!validatedPayload.success) {
|
|
5993
|
-
this.logger.error("Invalid payload for sendLoginEmail", validatedPayload.error);
|
|
5994
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5995
|
-
}
|
|
5996
|
-
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription/login_email", payload);
|
|
5997
|
-
return this.handleResponse(response, () => {
|
|
5998
|
-
if (!response.success) {
|
|
5999
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6000
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6001
|
-
if (response.status === 429) {
|
|
6002
|
-
return ["rate_limit_exceeded", error];
|
|
6003
|
-
}
|
|
6004
|
-
if (response.status === 404) {
|
|
6005
|
-
return ["not_found", error];
|
|
6006
|
-
}
|
|
6007
|
-
return ["server_error", error];
|
|
6008
|
-
}
|
|
6009
|
-
return [null, null];
|
|
6010
|
-
});
|
|
5601
|
+
catch (e) {
|
|
5602
|
+
throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);
|
|
6011
5603
|
}
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
if (response.status === 404) {
|
|
6036
|
-
return ["not_found", error];
|
|
6037
|
-
}
|
|
6038
|
-
return ["server_error", error];
|
|
6039
|
-
}
|
|
6040
|
-
const data = NewsletterSchema.parse(response.data);
|
|
6041
|
-
return [null, data];
|
|
6042
|
-
});
|
|
5604
|
+
}
|
|
5605
|
+
|
|
5606
|
+
/**
|
|
5607
|
+
* Removes a query parameter from the current URL and updates the browser history.
|
|
5608
|
+
* Uses `replaceState` to avoid adding a new history entry.
|
|
5609
|
+
*
|
|
5610
|
+
* @param param - The name of the query parameter to remove
|
|
5611
|
+
* @returns The value of the removed parameter, or null if it wasn't present
|
|
5612
|
+
*
|
|
5613
|
+
* @example
|
|
5614
|
+
* ```ts
|
|
5615
|
+
* // URL: https://example.com?token=abc123&foo=bar
|
|
5616
|
+
* const token = clearUrlParam("token");
|
|
5617
|
+
* // token = "abc123"
|
|
5618
|
+
* // URL is now: https://example.com?foo=bar
|
|
5619
|
+
* ```
|
|
5620
|
+
*/
|
|
5621
|
+
function clearUrlParam(param) {
|
|
5622
|
+
const url = new URL(window.location.href);
|
|
5623
|
+
const value = url.searchParams.get(param);
|
|
5624
|
+
if (value) {
|
|
5625
|
+
url.searchParams.delete(param);
|
|
5626
|
+
window.history.replaceState(null, "", url.toString());
|
|
6043
5627
|
}
|
|
5628
|
+
return value;
|
|
6044
5629
|
}
|
|
6045
5630
|
|
|
6046
|
-
|
|
6047
|
-
const
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
}
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
// Subscription schema based on SubscriptionSerializer
|
|
6088
|
-
const SubscriptionSchema = object({
|
|
6089
|
-
id: uuid(), // unidy_id
|
|
6090
|
-
title: string(),
|
|
6091
|
-
text: string(),
|
|
6092
|
-
payment_frequency: string().nullable(),
|
|
6093
|
-
metadata: record(string(), unknown()).nullable(),
|
|
6094
|
-
wallet_export: record(string(), unknown()).nullable(),
|
|
6095
|
-
state: string(),
|
|
6096
|
-
reference: string(),
|
|
6097
|
-
payment_state: string().nullable(),
|
|
6098
|
-
currency: string().nullable(),
|
|
6099
|
-
button_cta_url: string().nullable(),
|
|
6100
|
-
created_at: dateTransformer, // ISO8601(3) -> Date
|
|
6101
|
-
updated_at: dateTransformer, // ISO8601(3) -> Date
|
|
6102
|
-
starts_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6103
|
-
ends_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6104
|
-
next_payment_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6105
|
-
price: number(), // decimal(8, 2) -> float
|
|
6106
|
-
user_id: uuid(),
|
|
6107
|
-
subscription_category_id: uuid(),
|
|
6108
|
-
});
|
|
6109
|
-
// Subscriptions list response schema
|
|
6110
|
-
const SubscriptionsListResponseSchema = object({
|
|
6111
|
-
meta: PaginationMetaSchema,
|
|
6112
|
-
results: array(SubscriptionSchema),
|
|
6113
|
-
});
|
|
6114
|
-
|
|
6115
|
-
/**
|
|
6116
|
-
* Base service for ticketable resources (tickets and subscriptions).
|
|
6117
|
-
* Handles common query parameter building and response parsing.
|
|
6118
|
-
*/
|
|
6119
|
-
class TicketableService extends BaseService {
|
|
6120
|
-
/**
|
|
6121
|
-
* Builds query params from args, mapping camelCase to snake_case.
|
|
6122
|
-
* Returns undefined values filtered out.
|
|
6123
|
-
*/
|
|
6124
|
-
buildListParams(args = {}, categoryIdKey, categoryIdValue) {
|
|
6125
|
-
return {
|
|
6126
|
-
page: args.page,
|
|
6127
|
-
limit: args.perPage,
|
|
6128
|
-
state: args.state,
|
|
6129
|
-
payment_state: args.paymentState,
|
|
6130
|
-
order_by: args.orderBy,
|
|
6131
|
-
order_direction: args.orderDirection,
|
|
6132
|
-
service_id: args.serviceId,
|
|
6133
|
-
[categoryIdKey]: categoryIdValue,
|
|
6134
|
-
};
|
|
6135
|
-
}
|
|
6136
|
-
/**
|
|
6137
|
-
* Converts params to query string, filtering undefined/null and converting to strings.
|
|
6138
|
-
*/
|
|
6139
|
-
toQueryString(params) {
|
|
6140
|
-
const filtered = Object.entries(params)
|
|
6141
|
-
.filter(([_, v]) => v !== undefined && v !== null)
|
|
6142
|
-
.map(([k, v]) => [k, String(v)]);
|
|
6143
|
-
if (filtered.length === 0)
|
|
6144
|
-
return "";
|
|
6145
|
-
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
6146
|
-
}
|
|
6147
|
-
/**
|
|
6148
|
-
* Validates list arguments before making API request.
|
|
6149
|
-
* Uses Zod for input validation.
|
|
6150
|
-
*/
|
|
6151
|
-
validateListArgs(args) {
|
|
6152
|
-
const result = TicketableListParamsSchema.safeParse(args);
|
|
6153
|
-
if (!result.success) {
|
|
6154
|
-
this.logger.error("Invalid list parameters", result.error);
|
|
6155
|
-
return false;
|
|
6156
|
-
}
|
|
6157
|
-
return true;
|
|
5631
|
+
const logger = index.createLogger("PasskeyAuth");
|
|
5632
|
+
const PASSKEY_ERRORS = {
|
|
5633
|
+
NotSupportedError: "passkey_not_supported",
|
|
5634
|
+
NotAllowedError: "passkey_cancelled",
|
|
5635
|
+
SecurityError: "passkey_security_error",
|
|
5636
|
+
InvalidStateError: "passkey_invalid_state",
|
|
5637
|
+
};
|
|
5638
|
+
function decodeBase64Url(base64url) {
|
|
5639
|
+
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
5640
|
+
const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
|
|
5641
|
+
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
5642
|
+
}
|
|
5643
|
+
function buildPublicKeyOptions(options) {
|
|
5644
|
+
return {
|
|
5645
|
+
challenge: Uint8Array.from(atob(options.challenge), (c) => c.charCodeAt(0)),
|
|
5646
|
+
timeout: options.timeout || 60000,
|
|
5647
|
+
rpId: options.rpId,
|
|
5648
|
+
userVerification: options.userVerification || "required",
|
|
5649
|
+
allowCredentials: options.allowCredentials?.map((cred) => ({
|
|
5650
|
+
...cred,
|
|
5651
|
+
id: decodeBase64Url(cred.id),
|
|
5652
|
+
})),
|
|
5653
|
+
};
|
|
5654
|
+
}
|
|
5655
|
+
function formatCredentialForServer(credential) {
|
|
5656
|
+
const response = credential.response;
|
|
5657
|
+
return {
|
|
5658
|
+
id: credential.id,
|
|
5659
|
+
rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
|
|
5660
|
+
response: {
|
|
5661
|
+
authenticatorData: btoa(String.fromCharCode(...new Uint8Array(response.authenticatorData))),
|
|
5662
|
+
clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(response.clientDataJSON))),
|
|
5663
|
+
signature: btoa(String.fromCharCode(...new Uint8Array(response.signature))),
|
|
5664
|
+
},
|
|
5665
|
+
type: credential.type,
|
|
5666
|
+
};
|
|
5667
|
+
}
|
|
5668
|
+
function extractAndSetSignInId(tokenResponse) {
|
|
5669
|
+
if (tokenResponse.sid) {
|
|
5670
|
+
authStore.authStore.setSignInId(tokenResponse.sid);
|
|
5671
|
+
return;
|
|
6158
5672
|
}
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
if (!this.validateListArgs(args)) {
|
|
6165
|
-
return ["invalid_response", null]; // Invalid input treated same as invalid response
|
|
6166
|
-
}
|
|
6167
|
-
const idToken = await this.getIdToken();
|
|
6168
|
-
if (!idToken) {
|
|
6169
|
-
return ["missing_id_token", null];
|
|
5673
|
+
// Fallback: extract sid from JWT token payload
|
|
5674
|
+
try {
|
|
5675
|
+
const decoded = jwtDecode(tokenResponse.jwt);
|
|
5676
|
+
if (decoded.sid) {
|
|
5677
|
+
authStore.authStore.setSignInId(decoded.sid);
|
|
6170
5678
|
}
|
|
6171
|
-
const response = await this.client.get(`${endpoint}${queryString}`, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6172
|
-
return this.handleResponse(response, () => {
|
|
6173
|
-
if (!response.success) {
|
|
6174
|
-
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6175
|
-
return ["server_error", null];
|
|
6176
|
-
}
|
|
6177
|
-
const parsed = schema.safeParse(response.data);
|
|
6178
|
-
if (!parsed.success) {
|
|
6179
|
-
this.logger.error("Invalid response format", parsed.error);
|
|
6180
|
-
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6181
|
-
return ["invalid_response", null];
|
|
6182
|
-
}
|
|
6183
|
-
return [null, parsed.data];
|
|
6184
|
-
});
|
|
6185
5679
|
}
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
*/
|
|
6189
|
-
async handleGet(endpoint, schema, resourceName) {
|
|
6190
|
-
const idToken = await this.getIdToken();
|
|
6191
|
-
if (!idToken) {
|
|
6192
|
-
return ["missing_id_token", null];
|
|
6193
|
-
}
|
|
6194
|
-
const response = await this.client.get(endpoint, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6195
|
-
return this.handleResponse(response, () => {
|
|
6196
|
-
if (!response.success) {
|
|
6197
|
-
if (response.status === 404) {
|
|
6198
|
-
return ["not_found", null];
|
|
6199
|
-
}
|
|
6200
|
-
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6201
|
-
return ["server_error", null];
|
|
6202
|
-
}
|
|
6203
|
-
const parsed = schema.safeParse(response.data);
|
|
6204
|
-
if (!parsed.success) {
|
|
6205
|
-
this.logger.error("Invalid response format", parsed.error);
|
|
6206
|
-
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6207
|
-
return ["invalid_response", null];
|
|
6208
|
-
}
|
|
6209
|
-
return [null, parsed.data];
|
|
6210
|
-
});
|
|
5680
|
+
catch {
|
|
5681
|
+
// Failed to decode JWT token to extract sid, continue without it
|
|
6211
5682
|
}
|
|
6212
5683
|
}
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
async list(args = {}) {
|
|
6219
|
-
const params = this.buildListParams(args, "subscription_category_id", args.subscriptionCategoryId);
|
|
6220
|
-
const queryString = this.toQueryString(params);
|
|
6221
|
-
return this.handleList("/api/sdk/v1/subscriptions", queryString, SubscriptionsListResponseSchema, "subscriptions", args);
|
|
6222
|
-
}
|
|
6223
|
-
async get(args) {
|
|
6224
|
-
return this.handleGet(`/api/sdk/v1/subscriptions/${args.id}`, SubscriptionSchema, "subscription");
|
|
5684
|
+
function handlePasskeyError(error) {
|
|
5685
|
+
logger.error("Passkey error:", error);
|
|
5686
|
+
let errorMessage = "passkey_error";
|
|
5687
|
+
if (error instanceof DOMException) {
|
|
5688
|
+
errorMessage = PASSKEY_ERRORS[error.name] || "passkey_error";
|
|
6225
5689
|
}
|
|
5690
|
+
authStore.authStore.setFieldError("passkey", errorMessage);
|
|
5691
|
+
authStore.authStore.setLoading(false);
|
|
6226
5692
|
}
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
const queryString = this.toQueryString(params);
|
|
6235
|
-
return this.handleList("/api/sdk/v1/tickets", queryString, TicketsListResponseSchema, "tickets", args);
|
|
6236
|
-
}
|
|
6237
|
-
async get(args) {
|
|
6238
|
-
return this.handleGet(`/api/sdk/v1/tickets/${args.id}`, TicketSchema, "ticket");
|
|
6239
|
-
}
|
|
6240
|
-
}
|
|
6241
|
-
|
|
6242
|
-
class InvalidTokenError extends Error {
|
|
6243
|
-
}
|
|
6244
|
-
InvalidTokenError.prototype.name = "InvalidTokenError";
|
|
6245
|
-
function b64DecodeUnicode(str) {
|
|
6246
|
-
return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {
|
|
6247
|
-
let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
6248
|
-
if (code.length < 2) {
|
|
6249
|
-
code = "0" + code;
|
|
6250
|
-
}
|
|
6251
|
-
return "%" + code;
|
|
6252
|
-
}));
|
|
6253
|
-
}
|
|
6254
|
-
function base64UrlDecode(str) {
|
|
6255
|
-
let output = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
6256
|
-
switch (output.length % 4) {
|
|
6257
|
-
case 0:
|
|
6258
|
-
break;
|
|
6259
|
-
case 2:
|
|
6260
|
-
output += "==";
|
|
6261
|
-
break;
|
|
6262
|
-
case 3:
|
|
6263
|
-
output += "=";
|
|
6264
|
-
break;
|
|
6265
|
-
default:
|
|
6266
|
-
throw new Error("base64 string is not of the correct length");
|
|
6267
|
-
}
|
|
6268
|
-
try {
|
|
6269
|
-
return b64DecodeUnicode(output);
|
|
6270
|
-
}
|
|
6271
|
-
catch (err) {
|
|
6272
|
-
return atob(output);
|
|
6273
|
-
}
|
|
6274
|
-
}
|
|
6275
|
-
function jwtDecode(token, options) {
|
|
6276
|
-
if (typeof token !== "string") {
|
|
6277
|
-
throw new InvalidTokenError("Invalid token specified: must be a string");
|
|
6278
|
-
}
|
|
6279
|
-
options || (options = {});
|
|
6280
|
-
const pos = options.header === true ? 0 : 1;
|
|
6281
|
-
const part = token.split(".")[pos];
|
|
6282
|
-
if (typeof part !== "string") {
|
|
6283
|
-
throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);
|
|
6284
|
-
}
|
|
6285
|
-
let decoded;
|
|
6286
|
-
try {
|
|
6287
|
-
decoded = base64UrlDecode(part);
|
|
6288
|
-
}
|
|
6289
|
-
catch (e) {
|
|
6290
|
-
throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);
|
|
6291
|
-
}
|
|
6292
|
-
try {
|
|
6293
|
-
return JSON.parse(decoded);
|
|
6294
|
-
}
|
|
6295
|
-
catch (e) {
|
|
6296
|
-
throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);
|
|
6297
|
-
}
|
|
6298
|
-
}
|
|
6299
|
-
|
|
6300
|
-
const logger = index.createLogger("PasskeyAuth");
|
|
6301
|
-
const PASSKEY_ERRORS = {
|
|
6302
|
-
NotSupportedError: "passkey_not_supported",
|
|
6303
|
-
NotAllowedError: "passkey_cancelled",
|
|
6304
|
-
SecurityError: "passkey_security_error",
|
|
6305
|
-
InvalidStateError: "passkey_invalid_state",
|
|
6306
|
-
};
|
|
6307
|
-
function decodeBase64Url(base64url) {
|
|
6308
|
-
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
6309
|
-
const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
|
|
6310
|
-
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
6311
|
-
}
|
|
6312
|
-
function buildPublicKeyOptions(options) {
|
|
6313
|
-
return {
|
|
6314
|
-
challenge: Uint8Array.from(atob(options.challenge), (c) => c.charCodeAt(0)),
|
|
6315
|
-
timeout: options.timeout || 60000,
|
|
6316
|
-
rpId: options.rpId,
|
|
6317
|
-
userVerification: options.userVerification || "required",
|
|
6318
|
-
allowCredentials: options.allowCredentials?.map((cred) => ({
|
|
6319
|
-
...cred,
|
|
6320
|
-
id: decodeBase64Url(cred.id),
|
|
6321
|
-
})),
|
|
6322
|
-
};
|
|
6323
|
-
}
|
|
6324
|
-
function formatCredentialForServer(credential) {
|
|
6325
|
-
const response = credential.response;
|
|
6326
|
-
return {
|
|
6327
|
-
id: credential.id,
|
|
6328
|
-
rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
|
|
6329
|
-
response: {
|
|
6330
|
-
authenticatorData: btoa(String.fromCharCode(...new Uint8Array(response.authenticatorData))),
|
|
6331
|
-
clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(response.clientDataJSON))),
|
|
6332
|
-
signature: btoa(String.fromCharCode(...new Uint8Array(response.signature))),
|
|
6333
|
-
},
|
|
6334
|
-
type: credential.type,
|
|
6335
|
-
};
|
|
6336
|
-
}
|
|
6337
|
-
function extractAndSetSignInId(tokenResponse) {
|
|
6338
|
-
if (tokenResponse.sid) {
|
|
6339
|
-
authStore.authStore.setSignInId(tokenResponse.sid);
|
|
6340
|
-
return;
|
|
6341
|
-
}
|
|
6342
|
-
// Fallback: extract sid from JWT token payload
|
|
6343
|
-
try {
|
|
6344
|
-
const decoded = jwtDecode(tokenResponse.jwt);
|
|
6345
|
-
if (decoded.sid) {
|
|
6346
|
-
authStore.authStore.setSignInId(decoded.sid);
|
|
6347
|
-
}
|
|
6348
|
-
}
|
|
6349
|
-
catch {
|
|
6350
|
-
// Failed to decode JWT token to extract sid, continue without it
|
|
6351
|
-
}
|
|
6352
|
-
}
|
|
6353
|
-
function handlePasskeyError(error) {
|
|
6354
|
-
logger.error("Passkey error:", error);
|
|
6355
|
-
let errorMessage = "passkey_error";
|
|
6356
|
-
if (error instanceof DOMException) {
|
|
6357
|
-
errorMessage = PASSKEY_ERRORS[error.name] || "passkey_error";
|
|
6358
|
-
}
|
|
6359
|
-
authStore.authStore.setFieldError("passkey", errorMessage);
|
|
6360
|
-
authStore.authStore.setLoading(false);
|
|
6361
|
-
}
|
|
6362
|
-
async function authenticateWithPasskey(client, onSuccess) {
|
|
6363
|
-
authStore.authStore.setLoading(true);
|
|
6364
|
-
authStore.authStore.clearErrors();
|
|
6365
|
-
if (!window.PublicKeyCredential) {
|
|
6366
|
-
authStore.authStore.setFieldError("passkey", "passkey_not_supported");
|
|
6367
|
-
authStore.authStore.setLoading(false);
|
|
6368
|
-
return;
|
|
5693
|
+
async function authenticateWithPasskey(client, onSuccess) {
|
|
5694
|
+
authStore.authStore.setLoading(true);
|
|
5695
|
+
authStore.authStore.clearErrors();
|
|
5696
|
+
if (!window.PublicKeyCredential) {
|
|
5697
|
+
authStore.authStore.setFieldError("passkey", "passkey_not_supported");
|
|
5698
|
+
authStore.authStore.setLoading(false);
|
|
5699
|
+
return;
|
|
6369
5700
|
}
|
|
6370
5701
|
try {
|
|
6371
5702
|
const [optionsError, options] = await client.auth.getPasskeyOptions(authStore.state.sid ? { signInId: authStore.state.sid } : undefined);
|
|
@@ -6509,13 +5840,6 @@ class AuthHelpers {
|
|
|
6509
5840
|
return [error, _];
|
|
6510
5841
|
}
|
|
6511
5842
|
async refreshToken() {
|
|
6512
|
-
if (authStore.state.step === "missing-fields") {
|
|
6513
|
-
return;
|
|
6514
|
-
}
|
|
6515
|
-
const sid = componentUtils.clearUrlParam("sid");
|
|
6516
|
-
if (sid) {
|
|
6517
|
-
authStore.authStore.setSignInId(sid);
|
|
6518
|
-
}
|
|
6519
5843
|
if (!authStore.state.sid) {
|
|
6520
5844
|
this.logger.warn("No sign-in ID in the session");
|
|
6521
5845
|
return;
|
|
@@ -6529,6 +5853,12 @@ class AuthHelpers {
|
|
|
6529
5853
|
authStore.authStore.setToken(response.jwt);
|
|
6530
5854
|
}
|
|
6531
5855
|
}
|
|
5856
|
+
extractSidFromUrl() {
|
|
5857
|
+
const sid = clearUrlParam("sid");
|
|
5858
|
+
if (sid) {
|
|
5859
|
+
authStore.authStore.setSignInId(sid);
|
|
5860
|
+
}
|
|
5861
|
+
}
|
|
6532
5862
|
async checkSignedIn() {
|
|
6533
5863
|
if (authStore.state.authenticated)
|
|
6534
5864
|
return;
|
|
@@ -6571,307 +5901,1052 @@ class AuthHelpers {
|
|
|
6571
5901
|
}
|
|
6572
5902
|
return [error, response];
|
|
6573
5903
|
}
|
|
6574
|
-
async sendResetPasswordEmail() {
|
|
6575
|
-
if (!authStore.state.sid) {
|
|
6576
|
-
throw new Error(i18n.t("errors.no_sign_in_id"));
|
|
6577
|
-
}
|
|
6578
|
-
authStore.authStore.setLoading(true);
|
|
6579
|
-
authStore.authStore.setResetPasswordStep("requested");
|
|
6580
|
-
const [error, _] = await this.client.auth.sendResetPasswordEmail({
|
|
6581
|
-
signInId: authStore.state.sid,
|
|
6582
|
-
payload: { returnTo: window.location.href },
|
|
6583
|
-
});
|
|
6584
|
-
if (error) {
|
|
6585
|
-
authStore.authStore.setFieldError("resetPassword", error);
|
|
6586
|
-
}
|
|
6587
|
-
else {
|
|
6588
|
-
authStore.authStore.setResetPasswordStep("sent");
|
|
6589
|
-
authStore.authStore.clearErrors();
|
|
6590
|
-
}
|
|
6591
|
-
authStore.authStore.setLoading(false);
|
|
5904
|
+
async sendResetPasswordEmail() {
|
|
5905
|
+
if (!authStore.state.sid) {
|
|
5906
|
+
throw new Error(i18n.t("errors.no_sign_in_id"));
|
|
5907
|
+
}
|
|
5908
|
+
authStore.authStore.setLoading(true);
|
|
5909
|
+
authStore.authStore.setResetPasswordStep("requested");
|
|
5910
|
+
const [error, _] = await this.client.auth.sendResetPasswordEmail({
|
|
5911
|
+
signInId: authStore.state.sid,
|
|
5912
|
+
payload: { returnTo: window.location.href },
|
|
5913
|
+
});
|
|
5914
|
+
if (error) {
|
|
5915
|
+
authStore.authStore.setFieldError("resetPassword", error);
|
|
5916
|
+
}
|
|
5917
|
+
else {
|
|
5918
|
+
authStore.authStore.setResetPasswordStep("sent");
|
|
5919
|
+
authStore.authStore.clearErrors();
|
|
5920
|
+
}
|
|
5921
|
+
authStore.authStore.setLoading(false);
|
|
5922
|
+
}
|
|
5923
|
+
async resetPassword() {
|
|
5924
|
+
if (!authStore.state.resetPassword.token) {
|
|
5925
|
+
throw new Error("No reset token available");
|
|
5926
|
+
}
|
|
5927
|
+
if (!authStore.state.resetPassword.newPassword) {
|
|
5928
|
+
authStore.authStore.setFieldError("resetPassword", "password_required");
|
|
5929
|
+
return;
|
|
5930
|
+
}
|
|
5931
|
+
if (authStore.state.resetPassword.passwordConfirmation &&
|
|
5932
|
+
authStore.state.resetPassword.newPassword !== authStore.state.resetPassword.passwordConfirmation) {
|
|
5933
|
+
authStore.authStore.setFieldError("resetPassword", "passwords_do_not_match");
|
|
5934
|
+
return;
|
|
5935
|
+
}
|
|
5936
|
+
authStore.authStore.setLoading(true);
|
|
5937
|
+
authStore.authStore.clearErrors();
|
|
5938
|
+
const [error, response] = await this.client.auth.resetPassword({
|
|
5939
|
+
signInId: authStore.state.sid,
|
|
5940
|
+
token: authStore.state.resetPassword.token,
|
|
5941
|
+
payload: {
|
|
5942
|
+
password: authStore.state.resetPassword.newPassword,
|
|
5943
|
+
passwordConfirmation: authStore.state.resetPassword.passwordConfirmation,
|
|
5944
|
+
},
|
|
5945
|
+
});
|
|
5946
|
+
if (error) {
|
|
5947
|
+
authStore.authStore.setFieldError("resetPassword", error);
|
|
5948
|
+
// TODO: add proper password requirements handling --> for now this is fine
|
|
5949
|
+
if (error === "invalid_password") {
|
|
5950
|
+
authStore.authStore.setFieldError("password", response.error_details?.password.map((p) => i18n.t(`errors.password_requirements.${p}`)).join("\n"));
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
else {
|
|
5954
|
+
authStore.authStore.setStep("email");
|
|
5955
|
+
authStore.authStore.updateResetPassword({
|
|
5956
|
+
step: "completed",
|
|
5957
|
+
token: null,
|
|
5958
|
+
newPassword: "",
|
|
5959
|
+
passwordConfirmation: "",
|
|
5960
|
+
});
|
|
5961
|
+
clearUrlParam("reset_password_token");
|
|
5962
|
+
flashStore.Flash.success.addMessage("Password reset successfully");
|
|
5963
|
+
}
|
|
5964
|
+
authStore.authStore.setLoading(false);
|
|
5965
|
+
}
|
|
5966
|
+
async handleResetPasswordRedirect() {
|
|
5967
|
+
const url = new URL(window.location.href);
|
|
5968
|
+
const params = url.searchParams;
|
|
5969
|
+
const resetToken = params.get("reset_password_token");
|
|
5970
|
+
if (!resetToken) {
|
|
5971
|
+
return;
|
|
5972
|
+
}
|
|
5973
|
+
if (authStore.state.sid) {
|
|
5974
|
+
authStore.authStore.setLoading(true);
|
|
5975
|
+
const [error] = await this.client.auth.validateResetPasswordToken({
|
|
5976
|
+
signInId: authStore.state.sid,
|
|
5977
|
+
token: resetToken,
|
|
5978
|
+
});
|
|
5979
|
+
if (error) {
|
|
5980
|
+
authStore.authStore.setFieldError("resetPassword", error);
|
|
5981
|
+
authStore.authStore.setStep("reset-password");
|
|
5982
|
+
authStore.authStore.setLoading(false);
|
|
5983
|
+
return;
|
|
5984
|
+
}
|
|
5985
|
+
}
|
|
5986
|
+
authStore.authStore.setResetToken(resetToken);
|
|
5987
|
+
authStore.authStore.setStep("reset-password");
|
|
5988
|
+
authStore.authStore.setLoading(false);
|
|
5989
|
+
}
|
|
5990
|
+
handleSocialAuthRedirect() {
|
|
5991
|
+
const url = new URL(window.location.href);
|
|
5992
|
+
const params = url.searchParams;
|
|
5993
|
+
const error = params.get("error");
|
|
5994
|
+
// Not a social auth redirect (normal page load)
|
|
5995
|
+
if (!error && !params.has("sid")) {
|
|
5996
|
+
return;
|
|
5997
|
+
}
|
|
5998
|
+
// Handle successful social auth redirect
|
|
5999
|
+
if (!error && params.has("sid") && params.has("id_token")) {
|
|
6000
|
+
authStore.authStore.setSignInId(clearUrlParam("sid"));
|
|
6001
|
+
const idToken = clearUrlParam("id_token");
|
|
6002
|
+
if (idToken) {
|
|
6003
|
+
authStore.authStore.setToken(idToken);
|
|
6004
|
+
this.handleAuthSuccess({ jwt: idToken });
|
|
6005
|
+
}
|
|
6006
|
+
else {
|
|
6007
|
+
this.logger.error("No ID token found in the URL on social auth redirect");
|
|
6008
|
+
}
|
|
6009
|
+
return;
|
|
6010
|
+
}
|
|
6011
|
+
// Handle missing required fields
|
|
6012
|
+
if (error !== "missing_required_fields") {
|
|
6013
|
+
this.logger.error("Social auth redirect error:", error);
|
|
6014
|
+
return;
|
|
6015
|
+
}
|
|
6016
|
+
const fieldsFromUrl = clearUrlParam("fields");
|
|
6017
|
+
const sid = clearUrlParam("sid");
|
|
6018
|
+
clearUrlParam("error");
|
|
6019
|
+
if (!fieldsFromUrl || !sid) {
|
|
6020
|
+
return;
|
|
6021
|
+
}
|
|
6022
|
+
try {
|
|
6023
|
+
const fields = JSON.parse(fieldsFromUrl);
|
|
6024
|
+
authStore.authStore.setSignInId(sid);
|
|
6025
|
+
this.handleMissingFields(fields);
|
|
6026
|
+
}
|
|
6027
|
+
catch (e) {
|
|
6028
|
+
this.logger.error("Failed to parse missing fields payload:", e);
|
|
6029
|
+
authStore.authStore.setGlobalError("auth", "invalid_required_fields_payload");
|
|
6030
|
+
}
|
|
6031
|
+
}
|
|
6032
|
+
handleAuthError(error, response, fallbackField) {
|
|
6033
|
+
switch (error) {
|
|
6034
|
+
case "account_not_found":
|
|
6035
|
+
authStore.authStore.setFieldError("email", error);
|
|
6036
|
+
break;
|
|
6037
|
+
case "missing_required_fields": {
|
|
6038
|
+
const { fields, sid } = response;
|
|
6039
|
+
this.handleMissingFields(fields);
|
|
6040
|
+
if (sid) {
|
|
6041
|
+
authStore.authStore.setSignInId(sid);
|
|
6042
|
+
}
|
|
6043
|
+
break;
|
|
6044
|
+
}
|
|
6045
|
+
default:
|
|
6046
|
+
if (fallbackField === "password") {
|
|
6047
|
+
authStore.authStore.setFieldError("password", error);
|
|
6048
|
+
}
|
|
6049
|
+
else if (fallbackField === "magicCode") {
|
|
6050
|
+
authStore.authStore.setFieldError("magicCode", error);
|
|
6051
|
+
}
|
|
6052
|
+
else if (fallbackField === "email") {
|
|
6053
|
+
authStore.authStore.setFieldError("email", error);
|
|
6054
|
+
}
|
|
6055
|
+
else {
|
|
6056
|
+
// e.g. "account_locked", "internal_server_error"
|
|
6057
|
+
authStore.authStore.setGlobalError("auth", error);
|
|
6058
|
+
}
|
|
6059
|
+
break;
|
|
6060
|
+
}
|
|
6061
|
+
authStore.authStore.setLoading(false);
|
|
6062
|
+
}
|
|
6063
|
+
handleMissingFields(fields) {
|
|
6064
|
+
authStore.authStore.setMissingFields(fields);
|
|
6065
|
+
profileStore.state.data = fields;
|
|
6066
|
+
authStore.authStore.setStep("missing-fields");
|
|
6067
|
+
authStore.authStore.setLoading(false);
|
|
6068
|
+
}
|
|
6069
|
+
handleAuthSuccess(response) {
|
|
6070
|
+
authStore.authStore.setToken(response.jwt);
|
|
6071
|
+
authStore.authStore.setLoading(false);
|
|
6072
|
+
authStore.authStore.getRootComponentRef()?.onAuth(response);
|
|
6073
|
+
}
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6076
|
+
const DEFAULT_TOKEN_EXPIRATION_BUFFER_SECONDS = 10;
|
|
6077
|
+
class Auth {
|
|
6078
|
+
static instance;
|
|
6079
|
+
helpers;
|
|
6080
|
+
constructor(client) {
|
|
6081
|
+
this.helpers = new AuthHelpers(client);
|
|
6082
|
+
}
|
|
6083
|
+
static Errors = {
|
|
6084
|
+
email: {
|
|
6085
|
+
NOT_FOUND: "account_not_found",
|
|
6086
|
+
},
|
|
6087
|
+
magicCode: {
|
|
6088
|
+
RECENTLY_CREATED: "magic_code_recently_created",
|
|
6089
|
+
NOT_VALID: "magic_code_not_valid",
|
|
6090
|
+
EXPIRED: "magic_code_expired",
|
|
6091
|
+
USED: "magic_code_used",
|
|
6092
|
+
},
|
|
6093
|
+
password: {
|
|
6094
|
+
INVALID: "invalid_password",
|
|
6095
|
+
NOT_SET: "password_not_set",
|
|
6096
|
+
RESET_PASSWORD_ALREADY_SENT: "reset_password_already_sent",
|
|
6097
|
+
},
|
|
6098
|
+
general: {
|
|
6099
|
+
ACCOUNT_LOCKED: "account_locked",
|
|
6100
|
+
SIGN_IN_EXPIRED: "sign_in_expired",
|
|
6101
|
+
},
|
|
6102
|
+
};
|
|
6103
|
+
static async getInstance() {
|
|
6104
|
+
if (!Auth.isInitialized()) {
|
|
6105
|
+
await unidyStore.waitForConfig();
|
|
6106
|
+
return Auth.initialize(getUnidyClient());
|
|
6107
|
+
}
|
|
6108
|
+
return Auth.instance;
|
|
6109
|
+
}
|
|
6110
|
+
static async initialize(client) {
|
|
6111
|
+
if (Auth.instance) {
|
|
6112
|
+
return Auth.instance;
|
|
6113
|
+
}
|
|
6114
|
+
Auth.instance = new Auth(client);
|
|
6115
|
+
Auth.instance.helpers.handleSocialAuthRedirect();
|
|
6116
|
+
Auth.instance.helpers.extractSidFromUrl();
|
|
6117
|
+
await Auth.instance.helpers.handleResetPasswordRedirect();
|
|
6118
|
+
if (Auth.instance.isTokenValid(authStore.state.token)) {
|
|
6119
|
+
authStore.authStore.setAuthenticated(true);
|
|
6120
|
+
}
|
|
6121
|
+
return Auth.instance;
|
|
6122
|
+
}
|
|
6123
|
+
static isInitialized() {
|
|
6124
|
+
return !!Auth.instance;
|
|
6125
|
+
}
|
|
6126
|
+
/**
|
|
6127
|
+
* Checks whether a JWT token is valid and not expired.
|
|
6128
|
+
*
|
|
6129
|
+
* @param token - The JWT token to validate. Can be a raw JWT string, a decoded TokenPayload, or null.
|
|
6130
|
+
* @param expirationBuffer - Number of seconds before actual expiration to consider the token invalid, used to prevent race conditions with preemptive token refresh. Defaults to 10 seconds.
|
|
6131
|
+
* @returns `true` if the token is valid and won't expire within the buffer period, `false` otherwise.
|
|
6132
|
+
* @throws Error if expirationBuffer is not positive number
|
|
6133
|
+
*/
|
|
6134
|
+
isTokenValid(token, expirationBuffer = DEFAULT_TOKEN_EXPIRATION_BUFFER_SECONDS) {
|
|
6135
|
+
if (!Number.isFinite(expirationBuffer) || expirationBuffer <= 0) {
|
|
6136
|
+
throw new Error("expirationBuffer must be a positive finite number");
|
|
6137
|
+
}
|
|
6138
|
+
try {
|
|
6139
|
+
let decoded;
|
|
6140
|
+
if (typeof token === "string") {
|
|
6141
|
+
decoded = jwtDecode(token);
|
|
6142
|
+
}
|
|
6143
|
+
else {
|
|
6144
|
+
decoded = token;
|
|
6145
|
+
}
|
|
6146
|
+
if (!decoded)
|
|
6147
|
+
return false;
|
|
6148
|
+
if (typeof decoded.exp !== "number" || !Number.isFinite(decoded.exp)) {
|
|
6149
|
+
return false;
|
|
6150
|
+
}
|
|
6151
|
+
const currentTime = Date.now() / 1000;
|
|
6152
|
+
return decoded.exp > currentTime + expirationBuffer;
|
|
6153
|
+
}
|
|
6154
|
+
catch (error) {
|
|
6155
|
+
index.captureException(error);
|
|
6156
|
+
return false;
|
|
6157
|
+
}
|
|
6158
|
+
}
|
|
6159
|
+
async isAuthenticated() {
|
|
6160
|
+
const token = await this.getToken();
|
|
6161
|
+
return typeof token === "string";
|
|
6162
|
+
}
|
|
6163
|
+
async getToken() {
|
|
6164
|
+
const currentToken = authStore.state.token;
|
|
6165
|
+
if (currentToken && this.isTokenValid(currentToken)) {
|
|
6166
|
+
return currentToken;
|
|
6167
|
+
}
|
|
6168
|
+
await this.helpers.refreshToken();
|
|
6169
|
+
if (authStore.state.globalErrors.auth || !authStore.state.token) {
|
|
6170
|
+
return this.createAuthError(i18n.t("errors.refresh_failed"), "REFRESH_FAILED", true);
|
|
6171
|
+
}
|
|
6172
|
+
return authStore.state.token;
|
|
6173
|
+
}
|
|
6174
|
+
async userData() {
|
|
6175
|
+
const token = await this.getToken();
|
|
6176
|
+
if (typeof token !== "string") {
|
|
6177
|
+
return null;
|
|
6178
|
+
}
|
|
6179
|
+
if (!token) {
|
|
6180
|
+
return null;
|
|
6181
|
+
}
|
|
6182
|
+
try {
|
|
6183
|
+
return jwtDecode(token);
|
|
6184
|
+
}
|
|
6185
|
+
catch (error) {
|
|
6186
|
+
index.captureException(error);
|
|
6187
|
+
return null;
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6190
|
+
async logout() {
|
|
6191
|
+
const [error, _] = await this.helpers.logout();
|
|
6192
|
+
if (error) {
|
|
6193
|
+
return this.createAuthError(i18n.t("errors.sign_out_failed", { reason: error }), "SIGN_OUT_FAILED", false);
|
|
6194
|
+
}
|
|
6195
|
+
authStore.authStore.reset();
|
|
6196
|
+
return true;
|
|
6197
|
+
}
|
|
6198
|
+
getEmail() {
|
|
6199
|
+
return authStore.state.email;
|
|
6200
|
+
}
|
|
6201
|
+
createAuthError(message, code, requiresReauth = false) {
|
|
6202
|
+
const error = new Error(message);
|
|
6203
|
+
error.code = code;
|
|
6204
|
+
error.requiresReauth = requiresReauth;
|
|
6205
|
+
return error;
|
|
6206
|
+
}
|
|
6207
|
+
}
|
|
6208
|
+
|
|
6209
|
+
// Salutation enum
|
|
6210
|
+
const SalutationEnum = _enum(["mr", "mrs", "mx"]);
|
|
6211
|
+
// Newsletter subscription from API
|
|
6212
|
+
const NewsletterSubscriptionSchema = object({
|
|
6213
|
+
id: number(),
|
|
6214
|
+
email: string(),
|
|
6215
|
+
newsletter_internal_name: string(),
|
|
6216
|
+
preference_identifiers: array(string()),
|
|
6217
|
+
preference_token: string(),
|
|
6218
|
+
confirmed_at: string().nullable(),
|
|
6219
|
+
});
|
|
6220
|
+
// Newsletter subscription error extends base error with typed meta
|
|
6221
|
+
const NewsletterSubscriptionErrorSchema = BaseErrorSchema.extend({
|
|
6222
|
+
error_details: record(string(), array(string())).optional(),
|
|
6223
|
+
meta: object({
|
|
6224
|
+
newsletter_internal_name: string(),
|
|
6225
|
+
}),
|
|
6226
|
+
});
|
|
6227
|
+
// Create subscriptions response
|
|
6228
|
+
const CreateSubscriptionsResponseSchema = object({
|
|
6229
|
+
results: array(NewsletterSubscriptionSchema),
|
|
6230
|
+
errors: array(NewsletterSubscriptionErrorSchema),
|
|
6231
|
+
});
|
|
6232
|
+
// Additional fields for subscription creation - using .partial() for all optional fields
|
|
6233
|
+
const AdditionalFieldsSchema = object({
|
|
6234
|
+
first_name: string().nullable(),
|
|
6235
|
+
last_name: string().nullable(),
|
|
6236
|
+
salutation: SalutationEnum.nullable(),
|
|
6237
|
+
phone_number: string().nullable(),
|
|
6238
|
+
date_of_birth: string().nullable(),
|
|
6239
|
+
company_name: string().nullable(),
|
|
6240
|
+
address_line_1: string().nullable(),
|
|
6241
|
+
address_line_2: string().nullable(),
|
|
6242
|
+
city: string().nullable(),
|
|
6243
|
+
postal_code: string().nullable(),
|
|
6244
|
+
country_code: string().nullable(),
|
|
6245
|
+
preferred_language: string().nullable(),
|
|
6246
|
+
custom_attributes: record(string(), unknown()).nullable(),
|
|
6247
|
+
})
|
|
6248
|
+
.partial();
|
|
6249
|
+
// Create subscriptions payload
|
|
6250
|
+
const CreateSubscriptionsPayloadSchema = object({
|
|
6251
|
+
email: string(),
|
|
6252
|
+
additional_fields: optional(AdditionalFieldsSchema),
|
|
6253
|
+
newsletter_subscriptions: array(object({
|
|
6254
|
+
newsletter_internal_name: string(),
|
|
6255
|
+
preference_identifiers: optional(array(string())),
|
|
6256
|
+
})),
|
|
6257
|
+
redirect_to_after_confirmation: optional(string()),
|
|
6258
|
+
});
|
|
6259
|
+
// Update subscription payload
|
|
6260
|
+
const UpdateSubscriptionPayloadSchema = object({
|
|
6261
|
+
preference_identifiers: array(string()),
|
|
6262
|
+
});
|
|
6263
|
+
// Login email payload
|
|
6264
|
+
const LoginEmailPayloadSchema = object({
|
|
6265
|
+
email: string(),
|
|
6266
|
+
redirect_uri: string(),
|
|
6267
|
+
});
|
|
6268
|
+
// Resend DOI payload
|
|
6269
|
+
const ResendDoiPayloadSchema = object({
|
|
6270
|
+
redirect_to_after_confirmation: string(),
|
|
6271
|
+
})
|
|
6272
|
+
.partial();
|
|
6273
|
+
// Preference schema
|
|
6274
|
+
const PreferenceSchema = object({
|
|
6275
|
+
id: number(),
|
|
6276
|
+
name: string(),
|
|
6277
|
+
description: string().nullable(),
|
|
6278
|
+
plugin_identifier: string().nullable(),
|
|
6279
|
+
position: number(),
|
|
6280
|
+
default: boolean(),
|
|
6281
|
+
hidden: boolean(),
|
|
6282
|
+
});
|
|
6283
|
+
// Preference group schema
|
|
6284
|
+
const PreferenceGroupSchema = object({
|
|
6285
|
+
id: number(),
|
|
6286
|
+
name: string(),
|
|
6287
|
+
position: number(),
|
|
6288
|
+
flat: boolean(),
|
|
6289
|
+
preferences: array(PreferenceSchema),
|
|
6290
|
+
});
|
|
6291
|
+
// Newsletter schema
|
|
6292
|
+
const NewsletterSchema = object({
|
|
6293
|
+
id: number(),
|
|
6294
|
+
internal_name: string(),
|
|
6295
|
+
default: boolean(),
|
|
6296
|
+
position: number(),
|
|
6297
|
+
opt_in_type: string(),
|
|
6298
|
+
title: string(),
|
|
6299
|
+
description: string().nullable(),
|
|
6300
|
+
created_at: string(),
|
|
6301
|
+
updated_at: string(),
|
|
6302
|
+
preference_groups: array(PreferenceGroupSchema),
|
|
6303
|
+
});
|
|
6304
|
+
// Newsletters list response
|
|
6305
|
+
const NewslettersResponseSchema = object({
|
|
6306
|
+
newsletters: array(NewsletterSchema),
|
|
6307
|
+
});
|
|
6308
|
+
// Delete subscription response
|
|
6309
|
+
const DeleteSubscriptionResponseSchema = object({
|
|
6310
|
+
new_preference_token: string(),
|
|
6311
|
+
})
|
|
6312
|
+
.nullable();
|
|
6313
|
+
// Generic newsletter error response (extends base error)
|
|
6314
|
+
const NewsletterErrorResponseSchema = BaseErrorSchema;
|
|
6315
|
+
|
|
6316
|
+
class NewsletterService extends BaseService {
|
|
6317
|
+
constructor(client, deps) {
|
|
6318
|
+
super(client, "NewsletterService", deps);
|
|
6319
|
+
}
|
|
6320
|
+
async buildNewsletterAuthHeaders(options) {
|
|
6321
|
+
const idToken = await this.getIdToken();
|
|
6322
|
+
return this.buildAuthHeaders({
|
|
6323
|
+
"X-ID-Token": idToken ?? undefined,
|
|
6324
|
+
"X-Preference-Token": options?.preferenceToken,
|
|
6325
|
+
});
|
|
6326
|
+
}
|
|
6327
|
+
/**
|
|
6328
|
+
* Create newsletter subscriptions for a user
|
|
6329
|
+
*/
|
|
6330
|
+
async create(args) {
|
|
6331
|
+
const { payload, options } = args;
|
|
6332
|
+
const validatedPayload = CreateSubscriptionsPayloadSchema.safeParse(payload);
|
|
6333
|
+
if (!validatedPayload.success) {
|
|
6334
|
+
this.logger.error("Invalid payload for create", validatedPayload.error);
|
|
6335
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6336
|
+
}
|
|
6337
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6338
|
+
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription", payload, headers);
|
|
6339
|
+
return this.handleResponse(response, () => {
|
|
6340
|
+
// Both success and 422 return CreateSubscriptionsResponse
|
|
6341
|
+
if (response.success || response.status === 422) {
|
|
6342
|
+
const data = CreateSubscriptionsResponseSchema.parse(response.data);
|
|
6343
|
+
if (data.errors.length > 0) {
|
|
6344
|
+
return ["newsletter_error", data];
|
|
6345
|
+
}
|
|
6346
|
+
return [null, data];
|
|
6347
|
+
}
|
|
6348
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6349
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6350
|
+
switch (response.status) {
|
|
6351
|
+
case 401:
|
|
6352
|
+
return ["unauthorized", error];
|
|
6353
|
+
case 429:
|
|
6354
|
+
this.logger.warn("Rate limit exceeded");
|
|
6355
|
+
return ["rate_limit_exceeded", error];
|
|
6356
|
+
case 500:
|
|
6357
|
+
this.errorReporter.captureException(response);
|
|
6358
|
+
return ["server_error", error];
|
|
6359
|
+
default:
|
|
6360
|
+
return ["server_error", error];
|
|
6361
|
+
}
|
|
6362
|
+
});
|
|
6363
|
+
}
|
|
6364
|
+
/**
|
|
6365
|
+
* List all subscriptions for the authenticated user
|
|
6366
|
+
*/
|
|
6367
|
+
async list(args) {
|
|
6368
|
+
const headers = await this.buildNewsletterAuthHeaders(args?.options);
|
|
6369
|
+
const response = await this.client.get("/api/sdk/v1/newsletters/newsletter_subscription", headers);
|
|
6370
|
+
return this.handleResponse(response, () => {
|
|
6371
|
+
if (!response.success) {
|
|
6372
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6373
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6374
|
+
if (response.status === 401) {
|
|
6375
|
+
return ["unauthorized", error];
|
|
6376
|
+
}
|
|
6377
|
+
return ["server_error", error];
|
|
6378
|
+
}
|
|
6379
|
+
const data = array(NewsletterSubscriptionSchema).parse(response.data);
|
|
6380
|
+
return [null, data];
|
|
6381
|
+
});
|
|
6382
|
+
}
|
|
6383
|
+
/**
|
|
6384
|
+
* Get a specific subscription by newsletter internal name
|
|
6385
|
+
*/
|
|
6386
|
+
async get(args) {
|
|
6387
|
+
const { internalName, options } = args;
|
|
6388
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6389
|
+
const response = await this.client.get(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
6390
|
+
return this.handleResponse(response, () => {
|
|
6391
|
+
if (!response.success) {
|
|
6392
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6393
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6394
|
+
if (response.status === 401) {
|
|
6395
|
+
return ["unauthorized", error];
|
|
6396
|
+
}
|
|
6397
|
+
if (response.status === 404) {
|
|
6398
|
+
return ["not_found", error];
|
|
6399
|
+
}
|
|
6400
|
+
return ["server_error", error];
|
|
6401
|
+
}
|
|
6402
|
+
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
6403
|
+
return [null, data];
|
|
6404
|
+
});
|
|
6405
|
+
}
|
|
6406
|
+
/**
|
|
6407
|
+
* Update a subscription's preferences
|
|
6408
|
+
*/
|
|
6409
|
+
async update(args) {
|
|
6410
|
+
const { internalName, payload, options } = args;
|
|
6411
|
+
const validatedPayload = UpdateSubscriptionPayloadSchema.safeParse(payload);
|
|
6412
|
+
if (!validatedPayload.success) {
|
|
6413
|
+
this.logger.error("Invalid payload for update", validatedPayload.error);
|
|
6414
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6415
|
+
}
|
|
6416
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6417
|
+
const response = await this.client.patch(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, payload, headers);
|
|
6418
|
+
return this.handleResponse(response, () => {
|
|
6419
|
+
if (!response.success) {
|
|
6420
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6421
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6422
|
+
if (response.status === 401) {
|
|
6423
|
+
return ["unauthorized", error];
|
|
6424
|
+
}
|
|
6425
|
+
if (response.status === 404) {
|
|
6426
|
+
return ["not_found", error];
|
|
6427
|
+
}
|
|
6428
|
+
return ["server_error", error];
|
|
6429
|
+
}
|
|
6430
|
+
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
6431
|
+
return [null, data];
|
|
6432
|
+
});
|
|
6433
|
+
}
|
|
6434
|
+
/**
|
|
6435
|
+
* Delete a subscription
|
|
6436
|
+
*/
|
|
6437
|
+
async delete(args) {
|
|
6438
|
+
const { internalName, options } = args;
|
|
6439
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6440
|
+
const response = await this.client.delete(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
6441
|
+
return this.handleResponse(response, () => {
|
|
6442
|
+
if (!response.success) {
|
|
6443
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6444
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6445
|
+
if (response.status === 401) {
|
|
6446
|
+
return ["unauthorized", error];
|
|
6447
|
+
}
|
|
6448
|
+
if (response.status === 404) {
|
|
6449
|
+
return ["not_found", error];
|
|
6450
|
+
}
|
|
6451
|
+
if (response.status === 422) {
|
|
6452
|
+
return ["unprocessable_entity", error];
|
|
6453
|
+
}
|
|
6454
|
+
return ["server_error", error];
|
|
6455
|
+
}
|
|
6456
|
+
if (response.status === 204) {
|
|
6457
|
+
return [null, null];
|
|
6458
|
+
}
|
|
6459
|
+
const data = DeleteSubscriptionResponseSchema.parse(response.data);
|
|
6460
|
+
return [null, data];
|
|
6461
|
+
});
|
|
6462
|
+
}
|
|
6463
|
+
/**
|
|
6464
|
+
* Resend double opt-in confirmation email
|
|
6465
|
+
*/
|
|
6466
|
+
async resendDoi(args) {
|
|
6467
|
+
const { internalName, payload, options } = args;
|
|
6468
|
+
const validatedPayload = ResendDoiPayloadSchema.safeParse(payload);
|
|
6469
|
+
if (!validatedPayload.success) {
|
|
6470
|
+
this.logger.error("Invalid payload for resendDoi", validatedPayload.error);
|
|
6471
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6472
|
+
}
|
|
6473
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6474
|
+
const response = await this.client.post(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription/resend_doi`, payload, headers);
|
|
6475
|
+
return this.handleResponse(response, () => {
|
|
6476
|
+
if (!response.success) {
|
|
6477
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6478
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6479
|
+
if (response.status === 401) {
|
|
6480
|
+
return ["unauthorized", error];
|
|
6481
|
+
}
|
|
6482
|
+
if (response.status === 404) {
|
|
6483
|
+
return ["not_found", error];
|
|
6484
|
+
}
|
|
6485
|
+
if (error.error_identifier === "already_confirmed") {
|
|
6486
|
+
return ["already_confirmed", error];
|
|
6487
|
+
}
|
|
6488
|
+
return ["server_error", error];
|
|
6489
|
+
}
|
|
6490
|
+
return [null, null];
|
|
6491
|
+
});
|
|
6492
|
+
}
|
|
6493
|
+
/**
|
|
6494
|
+
* Send a login email for newsletter management
|
|
6495
|
+
*/
|
|
6496
|
+
async sendLoginEmail(args) {
|
|
6497
|
+
const { payload } = args;
|
|
6498
|
+
const validatedPayload = LoginEmailPayloadSchema.safeParse(payload);
|
|
6499
|
+
if (!validatedPayload.success) {
|
|
6500
|
+
this.logger.error("Invalid payload for sendLoginEmail", validatedPayload.error);
|
|
6501
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6502
|
+
}
|
|
6503
|
+
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription/login_email", payload);
|
|
6504
|
+
return this.handleResponse(response, () => {
|
|
6505
|
+
if (!response.success) {
|
|
6506
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6507
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6508
|
+
if (response.status === 429) {
|
|
6509
|
+
return ["rate_limit_exceeded", error];
|
|
6510
|
+
}
|
|
6511
|
+
if (response.status === 404) {
|
|
6512
|
+
return ["not_found", error];
|
|
6513
|
+
}
|
|
6514
|
+
return ["server_error", error];
|
|
6515
|
+
}
|
|
6516
|
+
return [null, null];
|
|
6517
|
+
});
|
|
6518
|
+
}
|
|
6519
|
+
/**
|
|
6520
|
+
* List all available newsletters
|
|
6521
|
+
*/
|
|
6522
|
+
async listAll() {
|
|
6523
|
+
const response = await this.client.get("/api/sdk/v1/newsletters");
|
|
6524
|
+
return this.handleResponse(response, () => {
|
|
6525
|
+
if (!response.success) {
|
|
6526
|
+
return ["server_error", null];
|
|
6527
|
+
}
|
|
6528
|
+
const data = NewslettersResponseSchema.parse(response.data);
|
|
6529
|
+
return [null, data];
|
|
6530
|
+
});
|
|
6531
|
+
}
|
|
6532
|
+
/**
|
|
6533
|
+
* Get a newsletter by its internal name
|
|
6534
|
+
*/
|
|
6535
|
+
async getByName(args) {
|
|
6536
|
+
const { internalName } = args;
|
|
6537
|
+
const response = await this.client.get(`/api/sdk/v1/newsletters/${internalName}`);
|
|
6538
|
+
return this.handleResponse(response, () => {
|
|
6539
|
+
if (!response.success) {
|
|
6540
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6541
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6542
|
+
if (response.status === 404) {
|
|
6543
|
+
return ["not_found", error];
|
|
6544
|
+
}
|
|
6545
|
+
return ["server_error", error];
|
|
6546
|
+
}
|
|
6547
|
+
const data = NewsletterSchema.parse(response.data);
|
|
6548
|
+
return [null, data];
|
|
6549
|
+
});
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
|
|
6553
|
+
// Export format and link response schemas
|
|
6554
|
+
const ExportFormat = _enum(["pdf", "pkpass"]);
|
|
6555
|
+
const ExportLinkResponseSchema = object({
|
|
6556
|
+
url: string().url(),
|
|
6557
|
+
expires_in: number(),
|
|
6558
|
+
});
|
|
6559
|
+
// Input validation schemas for ticketable list parameters
|
|
6560
|
+
const TicketableListParamsSchema = object({
|
|
6561
|
+
page: number().int().positive().optional(),
|
|
6562
|
+
perPage: number().int().positive().max(250).optional(),
|
|
6563
|
+
state: string().nullish(),
|
|
6564
|
+
paymentState: string().nullish(),
|
|
6565
|
+
orderBy: _enum(["starts_at", "ends_at", "reference", "created_at"]).optional(),
|
|
6566
|
+
orderDirection: _enum(["asc", "desc"]).optional(),
|
|
6567
|
+
serviceId: number().int().positive().optional(),
|
|
6568
|
+
});
|
|
6569
|
+
// Date transformer for ISO8601 strings
|
|
6570
|
+
const dateTransformer = date();
|
|
6571
|
+
const nullableDateTransformer = date().nullable();
|
|
6572
|
+
// Ticket schema based on TicketSerializer
|
|
6573
|
+
const TicketSchema = object({
|
|
6574
|
+
id: uuid(), // unidy_id
|
|
6575
|
+
title: string(),
|
|
6576
|
+
text: string().nullable(),
|
|
6577
|
+
reference: string(),
|
|
6578
|
+
metadata: record(string(), unknown()).nullable(),
|
|
6579
|
+
wallet_export: record(string(), unknown()).nullable(),
|
|
6580
|
+
exportable_to_wallet: boolean(),
|
|
6581
|
+
state: string(),
|
|
6582
|
+
payment_state: string().nullable(),
|
|
6583
|
+
button_cta_url: string().nullable(),
|
|
6584
|
+
info_banner: string().nullable(),
|
|
6585
|
+
seating: string().nullable(),
|
|
6586
|
+
venue: string().nullable(),
|
|
6587
|
+
currency: string().nullable(),
|
|
6588
|
+
starts_at: dateTransformer, // ISO8601(3) -> Date
|
|
6589
|
+
ends_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6590
|
+
created_at: dateTransformer, // ISO8601(3) -> Date
|
|
6591
|
+
updated_at: dateTransformer, // ISO8601(3) -> Date
|
|
6592
|
+
price: number(), // decimal(8, 2) -> float
|
|
6593
|
+
user_id: uuid(),
|
|
6594
|
+
ticket_category_id: uuid(),
|
|
6595
|
+
});
|
|
6596
|
+
// Tickets list response schema
|
|
6597
|
+
const TicketsListResponseSchema = object({
|
|
6598
|
+
meta: PaginationMetaSchema,
|
|
6599
|
+
results: array(TicketSchema),
|
|
6600
|
+
});
|
|
6601
|
+
// Subscription schema based on SubscriptionSerializer
|
|
6602
|
+
const SubscriptionSchema = object({
|
|
6603
|
+
id: uuid(), // unidy_id
|
|
6604
|
+
title: string(),
|
|
6605
|
+
text: string(),
|
|
6606
|
+
payment_frequency: string().nullable(),
|
|
6607
|
+
metadata: record(string(), unknown()).nullable(),
|
|
6608
|
+
wallet_export: record(string(), unknown()).nullable(),
|
|
6609
|
+
exportable_to_wallet: boolean(),
|
|
6610
|
+
state: string(),
|
|
6611
|
+
reference: string(),
|
|
6612
|
+
payment_state: string().nullable(),
|
|
6613
|
+
currency: string().nullable(),
|
|
6614
|
+
button_cta_url: string().nullable(),
|
|
6615
|
+
created_at: dateTransformer, // ISO8601(3) -> Date
|
|
6616
|
+
updated_at: dateTransformer, // ISO8601(3) -> Date
|
|
6617
|
+
starts_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6618
|
+
ends_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6619
|
+
next_payment_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6620
|
+
price: number(), // decimal(8, 2) -> float
|
|
6621
|
+
user_id: uuid(),
|
|
6622
|
+
subscription_category_id: uuid(),
|
|
6623
|
+
});
|
|
6624
|
+
// Subscriptions list response schema
|
|
6625
|
+
const SubscriptionsListResponseSchema = object({
|
|
6626
|
+
meta: PaginationMetaSchema,
|
|
6627
|
+
results: array(SubscriptionSchema),
|
|
6628
|
+
});
|
|
6629
|
+
|
|
6630
|
+
/**
|
|
6631
|
+
* Base service for ticketable resources (tickets and subscriptions).
|
|
6632
|
+
* Handles common query parameter building and response parsing.
|
|
6633
|
+
*/
|
|
6634
|
+
class TicketableService extends BaseService {
|
|
6635
|
+
/**
|
|
6636
|
+
* Builds query params from args, mapping camelCase to snake_case.
|
|
6637
|
+
* Returns undefined values filtered out.
|
|
6638
|
+
*/
|
|
6639
|
+
buildListParams(args = {}, categoryIdKey, categoryIdValue) {
|
|
6640
|
+
return {
|
|
6641
|
+
page: args.page,
|
|
6642
|
+
limit: args.perPage,
|
|
6643
|
+
state: args.state,
|
|
6644
|
+
payment_state: args.paymentState,
|
|
6645
|
+
order_by: args.orderBy,
|
|
6646
|
+
order_direction: args.orderDirection,
|
|
6647
|
+
service_id: args.serviceId,
|
|
6648
|
+
[categoryIdKey]: categoryIdValue,
|
|
6649
|
+
};
|
|
6650
|
+
}
|
|
6651
|
+
/**
|
|
6652
|
+
* Converts params to query string, filtering undefined/null and converting to strings.
|
|
6653
|
+
*/
|
|
6654
|
+
toQueryString(params) {
|
|
6655
|
+
const filtered = Object.entries(params)
|
|
6656
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
6657
|
+
.map(([k, v]) => [k, String(v)]);
|
|
6658
|
+
if (filtered.length === 0)
|
|
6659
|
+
return "";
|
|
6660
|
+
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
6592
6661
|
}
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6662
|
+
/**
|
|
6663
|
+
* Validates list arguments before making API request.
|
|
6664
|
+
* Uses Zod for input validation.
|
|
6665
|
+
*/
|
|
6666
|
+
validateListArgs(args) {
|
|
6667
|
+
const result = TicketableListParamsSchema.safeParse(args);
|
|
6668
|
+
if (!result.success) {
|
|
6669
|
+
this.logger.error("Invalid list parameters", result.error);
|
|
6670
|
+
return false;
|
|
6596
6671
|
}
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6672
|
+
return true;
|
|
6673
|
+
}
|
|
6674
|
+
/**
|
|
6675
|
+
* Generic list handler with schema validation.
|
|
6676
|
+
*/
|
|
6677
|
+
async handleList(endpoint, queryString, schema, resourceName, args = {}) {
|
|
6678
|
+
// Validate input parameters
|
|
6679
|
+
if (!this.validateListArgs(args)) {
|
|
6680
|
+
return ["invalid_response", null]; // Invalid input treated same as invalid response
|
|
6600
6681
|
}
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
return;
|
|
6682
|
+
const idToken = await this.getIdToken();
|
|
6683
|
+
if (!idToken) {
|
|
6684
|
+
return ["missing_id_token", null];
|
|
6605
6685
|
}
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
payload: {
|
|
6612
|
-
password: authStore.state.resetPassword.newPassword,
|
|
6613
|
-
passwordConfirmation: authStore.state.resetPassword.passwordConfirmation,
|
|
6614
|
-
},
|
|
6615
|
-
});
|
|
6616
|
-
if (error) {
|
|
6617
|
-
authStore.authStore.setFieldError("resetPassword", error);
|
|
6618
|
-
// TODO: add proper password requirements handling --> for now this is fine
|
|
6619
|
-
if (error === "invalid_password") {
|
|
6620
|
-
authStore.authStore.setFieldError("password", response.error_details?.password.map((p) => i18n.t(`errors.password_requirements.${p}`)).join("\n"));
|
|
6686
|
+
const response = await this.client.get(`${endpoint}${queryString}`, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6687
|
+
return this.handleResponse(response, () => {
|
|
6688
|
+
if (!response.success) {
|
|
6689
|
+
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6690
|
+
return ["server_error", null];
|
|
6621
6691
|
}
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
token: null,
|
|
6628
|
-
newPassword: "",
|
|
6629
|
-
passwordConfirmation: "",
|
|
6630
|
-
});
|
|
6631
|
-
componentUtils.clearUrlParam("reset_password_token");
|
|
6632
|
-
flashStore.Flash.success.addMessage("Password reset successfully");
|
|
6633
|
-
}
|
|
6634
|
-
authStore.authStore.setLoading(false);
|
|
6635
|
-
}
|
|
6636
|
-
async handleResetPasswordRedirect() {
|
|
6637
|
-
const url = new URL(window.location.href);
|
|
6638
|
-
const params = url.searchParams;
|
|
6639
|
-
const resetToken = params.get("reset_password_token");
|
|
6640
|
-
if (!resetToken) {
|
|
6641
|
-
return;
|
|
6642
|
-
}
|
|
6643
|
-
if (authStore.state.sid) {
|
|
6644
|
-
authStore.authStore.setLoading(true);
|
|
6645
|
-
const [error] = await this.client.auth.validateResetPasswordToken({
|
|
6646
|
-
signInId: authStore.state.sid,
|
|
6647
|
-
token: resetToken,
|
|
6648
|
-
});
|
|
6649
|
-
if (error) {
|
|
6650
|
-
authStore.authStore.setFieldError("resetPassword", error);
|
|
6651
|
-
authStore.authStore.setStep("reset-password");
|
|
6652
|
-
authStore.authStore.setLoading(false);
|
|
6653
|
-
return;
|
|
6692
|
+
const parsed = schema.safeParse(response.data);
|
|
6693
|
+
if (!parsed.success) {
|
|
6694
|
+
this.logger.error("Invalid response format", parsed.error);
|
|
6695
|
+
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6696
|
+
return ["invalid_response", null];
|
|
6654
6697
|
}
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
authStore.authStore.setStep("reset-password");
|
|
6658
|
-
authStore.authStore.setLoading(false);
|
|
6698
|
+
return [null, parsed.data];
|
|
6699
|
+
});
|
|
6659
6700
|
}
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
if (!
|
|
6666
|
-
return;
|
|
6701
|
+
/**
|
|
6702
|
+
* Generic get handler with schema validation.
|
|
6703
|
+
*/
|
|
6704
|
+
async handleGet(endpoint, schema, resourceName) {
|
|
6705
|
+
const idToken = await this.getIdToken();
|
|
6706
|
+
if (!idToken) {
|
|
6707
|
+
return ["missing_id_token", null];
|
|
6667
6708
|
}
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
this.
|
|
6709
|
+
const response = await this.client.get(endpoint, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6710
|
+
return this.handleResponse(response, () => {
|
|
6711
|
+
if (!response.success) {
|
|
6712
|
+
if (response.status === 404) {
|
|
6713
|
+
return ["not_found", null];
|
|
6714
|
+
}
|
|
6715
|
+
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6716
|
+
return ["server_error", null];
|
|
6675
6717
|
}
|
|
6676
|
-
|
|
6677
|
-
|
|
6718
|
+
const parsed = schema.safeParse(response.data);
|
|
6719
|
+
if (!parsed.success) {
|
|
6720
|
+
this.logger.error("Invalid response format", parsed.error);
|
|
6721
|
+
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6722
|
+
return ["invalid_response", null];
|
|
6678
6723
|
}
|
|
6679
|
-
return;
|
|
6680
|
-
}
|
|
6681
|
-
// Handle missing required fields
|
|
6682
|
-
if (error !== "missing_required_fields") {
|
|
6683
|
-
this.logger.error("Social auth redirect error:", error);
|
|
6684
|
-
return;
|
|
6685
|
-
}
|
|
6686
|
-
const fieldsFromUrl = componentUtils.clearUrlParam("fields");
|
|
6687
|
-
const sid = componentUtils.clearUrlParam("sid");
|
|
6688
|
-
componentUtils.clearUrlParam("error");
|
|
6689
|
-
if (!fieldsFromUrl || !sid) {
|
|
6690
|
-
return;
|
|
6691
|
-
}
|
|
6692
|
-
try {
|
|
6693
|
-
const fields = JSON.parse(fieldsFromUrl);
|
|
6694
|
-
authStore.authStore.setSignInId(sid);
|
|
6695
|
-
this.handleMissingFields(fields);
|
|
6696
|
-
}
|
|
6697
|
-
catch (e) {
|
|
6698
|
-
this.logger.error("Failed to parse missing fields payload:", e);
|
|
6699
|
-
authStore.authStore.setGlobalError("auth", "invalid_required_fields_payload");
|
|
6700
|
-
}
|
|
6724
|
+
return [null, parsed.data];
|
|
6725
|
+
});
|
|
6701
6726
|
}
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6727
|
+
}
|
|
6728
|
+
|
|
6729
|
+
class SubscriptionsService extends TicketableService {
|
|
6730
|
+
constructor(client, deps) {
|
|
6731
|
+
super(client, "SubscriptionsService", deps);
|
|
6732
|
+
}
|
|
6733
|
+
async list(args = {}) {
|
|
6734
|
+
const params = this.buildListParams(args, "subscription_category_id", args.subscriptionCategoryId);
|
|
6735
|
+
const queryString = this.toQueryString(params);
|
|
6736
|
+
return this.handleList("/api/sdk/v1/subscriptions", queryString, SubscriptionsListResponseSchema, "subscriptions", args);
|
|
6737
|
+
}
|
|
6738
|
+
async get(args) {
|
|
6739
|
+
return this.handleGet(`/api/sdk/v1/subscriptions/${args.id}`, SubscriptionSchema, "subscription");
|
|
6740
|
+
}
|
|
6741
|
+
async getExportLink(args) {
|
|
6742
|
+
const idToken = await this.getIdToken();
|
|
6743
|
+
if (!idToken) {
|
|
6744
|
+
return ["missing_id_token", null];
|
|
6745
|
+
}
|
|
6746
|
+
const response = await this.client.post(`/api/sdk/v1/subscriptions/${args.id}/export_link`, { format: args.format }, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6747
|
+
return this.handleResponse(response, () => {
|
|
6748
|
+
if (!response.success) {
|
|
6749
|
+
if (response.status === 401 || response.status === 403) {
|
|
6750
|
+
return ["unauthorized", null];
|
|
6712
6751
|
}
|
|
6713
|
-
|
|
6752
|
+
return ["server_error", null];
|
|
6714
6753
|
}
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
else if (fallbackField === "email") {
|
|
6723
|
-
authStore.authStore.setFieldError("email", error);
|
|
6724
|
-
}
|
|
6725
|
-
else {
|
|
6726
|
-
// e.g. "account_locked", "internal_server_error"
|
|
6727
|
-
authStore.authStore.setGlobalError("auth", error);
|
|
6728
|
-
}
|
|
6729
|
-
break;
|
|
6730
|
-
}
|
|
6731
|
-
authStore.authStore.setLoading(false);
|
|
6754
|
+
const parsed = ExportLinkResponseSchema.safeParse(response.data);
|
|
6755
|
+
if (!parsed.success) {
|
|
6756
|
+
this.logger.error("Invalid export link response", parsed.error);
|
|
6757
|
+
return ["invalid_response", null];
|
|
6758
|
+
}
|
|
6759
|
+
return [null, parsed.data];
|
|
6760
|
+
});
|
|
6732
6761
|
}
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6762
|
+
}
|
|
6763
|
+
|
|
6764
|
+
class TicketsService extends TicketableService {
|
|
6765
|
+
constructor(client, deps) {
|
|
6766
|
+
super(client, "TicketsService", deps);
|
|
6738
6767
|
}
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6768
|
+
async list(args = {}) {
|
|
6769
|
+
const params = this.buildListParams(args, "ticket_category_id", args.ticketCategoryId);
|
|
6770
|
+
const queryString = this.toQueryString(params);
|
|
6771
|
+
return this.handleList("/api/sdk/v1/tickets", queryString, TicketsListResponseSchema, "tickets", args);
|
|
6772
|
+
}
|
|
6773
|
+
async get(args) {
|
|
6774
|
+
return this.handleGet(`/api/sdk/v1/tickets/${args.id}`, TicketSchema, "ticket");
|
|
6775
|
+
}
|
|
6776
|
+
async getExportLink(args) {
|
|
6777
|
+
const idToken = await this.getIdToken();
|
|
6778
|
+
if (!idToken) {
|
|
6779
|
+
return ["missing_id_token", null];
|
|
6780
|
+
}
|
|
6781
|
+
const response = await this.client.post(`/api/sdk/v1/tickets/${args.id}/export_link`, { format: args.format }, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6782
|
+
return this.handleResponse(response, () => {
|
|
6783
|
+
if (!response.success) {
|
|
6784
|
+
if (response.status === 401 || response.status === 403) {
|
|
6785
|
+
return ["unauthorized", null];
|
|
6786
|
+
}
|
|
6787
|
+
return ["server_error", null];
|
|
6788
|
+
}
|
|
6789
|
+
const parsed = ExportLinkResponseSchema.safeParse(response.data);
|
|
6790
|
+
if (!parsed.success) {
|
|
6791
|
+
this.logger.error("Invalid export link response", parsed.error);
|
|
6792
|
+
return ["invalid_response", null];
|
|
6793
|
+
}
|
|
6794
|
+
return [null, parsed.data];
|
|
6795
|
+
});
|
|
6743
6796
|
}
|
|
6744
6797
|
}
|
|
6745
6798
|
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6799
|
+
/**
|
|
6800
|
+
* Base API client with shared functionality for both browser and standalone environments.
|
|
6801
|
+
*/
|
|
6802
|
+
/**
|
|
6803
|
+
* Abstract base class for API clients.
|
|
6804
|
+
* Provides shared functionality for making HTTP requests.
|
|
6805
|
+
*/
|
|
6806
|
+
class BaseApiClient {
|
|
6807
|
+
/**
|
|
6808
|
+
* Error messages that indicate a connection failure rather than a server error.
|
|
6809
|
+
* Grouped by source/environment.
|
|
6810
|
+
*/
|
|
6811
|
+
static CONNECTION_ERROR_MESSAGES = [
|
|
6812
|
+
// Browser fetch API errors
|
|
6813
|
+
"Failed to fetch", // Generic browser fetch failure (Chrome)
|
|
6814
|
+
"NetworkError", // Firefox network error
|
|
6815
|
+
"Load failed", // Safari network error
|
|
6816
|
+
"The network connection was lost", // Safari connection lost
|
|
6817
|
+
// Chromium/V8 error codes (used by Node.js and Chrome)
|
|
6818
|
+
"ERR_CONNECTION_REFUSED", // Server not accepting connections
|
|
6819
|
+
"ERR_NETWORK", // General network error
|
|
6820
|
+
"ERR_INTERNET_DISCONNECTED", // No internet connection
|
|
6821
|
+
// Node.js system error codes
|
|
6822
|
+
"ECONNREFUSED", // Connection refused by server
|
|
6823
|
+
"ENOTFOUND", // DNS lookup failed
|
|
6824
|
+
"EAI_AGAIN", // Temporary DNS failure
|
|
6825
|
+
];
|
|
6826
|
+
onConnectionChange;
|
|
6827
|
+
baseUrl;
|
|
6828
|
+
api_key;
|
|
6829
|
+
constructor(config) {
|
|
6830
|
+
this.baseUrl = config.baseUrl;
|
|
6831
|
+
this.api_key = config.apiKey;
|
|
6832
|
+
this.onConnectionChange = config.onConnectionChange;
|
|
6752
6833
|
}
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
},
|
|
6757
|
-
magicCode: {
|
|
6758
|
-
RECENTLY_CREATED: "magic_code_recently_created",
|
|
6759
|
-
NOT_VALID: "magic_code_not_valid",
|
|
6760
|
-
EXPIRED: "magic_code_expired",
|
|
6761
|
-
USED: "magic_code_used",
|
|
6762
|
-
},
|
|
6763
|
-
password: {
|
|
6764
|
-
INVALID: "invalid_password",
|
|
6765
|
-
NOT_SET: "password_not_set",
|
|
6766
|
-
RESET_PASSWORD_ALREADY_SENT: "reset_password_already_sent",
|
|
6767
|
-
},
|
|
6768
|
-
general: {
|
|
6769
|
-
ACCOUNT_LOCKED: "account_locked",
|
|
6770
|
-
SIGN_IN_EXPIRED: "sign_in_expired",
|
|
6771
|
-
},
|
|
6772
|
-
};
|
|
6773
|
-
static async getInstance() {
|
|
6774
|
-
if (!Auth.isInitialized()) {
|
|
6775
|
-
await unidyStore.waitForConfig();
|
|
6776
|
-
return Auth.initialize(getUnidyClient());
|
|
6834
|
+
isConnectionError(error) {
|
|
6835
|
+
if (error instanceof Error) {
|
|
6836
|
+
return BaseApiClient.CONNECTION_ERROR_MESSAGES.some((msg) => error.message.includes(msg));
|
|
6777
6837
|
}
|
|
6778
|
-
return
|
|
6838
|
+
return false;
|
|
6779
6839
|
}
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
return Auth.instance;
|
|
6783
|
-
}
|
|
6784
|
-
Auth.instance = new Auth(client);
|
|
6785
|
-
Auth.instance.helpers.handleSocialAuthRedirect();
|
|
6786
|
-
await Auth.instance.helpers.handleResetPasswordRedirect();
|
|
6787
|
-
if (Auth.instance.isTokenValid(authStore.state.token)) {
|
|
6788
|
-
authStore.authStore.setAuthenticated(true);
|
|
6789
|
-
}
|
|
6790
|
-
return Auth.instance;
|
|
6840
|
+
setConnectionStatus(isConnected) {
|
|
6841
|
+
this.onConnectionChange?.(isConnected);
|
|
6791
6842
|
}
|
|
6792
|
-
|
|
6793
|
-
|
|
6843
|
+
baseHeaders() {
|
|
6844
|
+
const h = new Headers();
|
|
6845
|
+
h.set("Content-Type", "application/json");
|
|
6846
|
+
h.set("Accept", "application/json");
|
|
6847
|
+
h.set("Authorization", `Bearer ${this.api_key}`);
|
|
6848
|
+
return h;
|
|
6849
|
+
}
|
|
6850
|
+
mergeHeaders(base, extra) {
|
|
6851
|
+
const out = new Headers(base);
|
|
6852
|
+
if (extra) {
|
|
6853
|
+
new Headers(extra).forEach((v, k) => {
|
|
6854
|
+
out.set(k, v);
|
|
6855
|
+
});
|
|
6856
|
+
}
|
|
6857
|
+
return out;
|
|
6794
6858
|
}
|
|
6795
6859
|
/**
|
|
6796
|
-
*
|
|
6797
|
-
*
|
|
6798
|
-
* @param token - The JWT token to validate. Can be a raw JWT string, a decoded TokenPayload, or null.
|
|
6799
|
-
* @param expirationBuffer - Number of seconds before actual expiration to consider the token invalid, used to prevent race conditions with preemptive token refresh. Defaults to 10 seconds.
|
|
6800
|
-
* @returns `true` if the token is valid and won't expire within the buffer period, `false` otherwise.
|
|
6801
|
-
* @throws Error if expirationBuffer is not positive number
|
|
6860
|
+
* Builds a query string from params, filtering out undefined/null values.
|
|
6802
6861
|
*/
|
|
6803
|
-
|
|
6804
|
-
if (!
|
|
6805
|
-
|
|
6806
|
-
|
|
6862
|
+
buildQueryString(params) {
|
|
6863
|
+
if (!params)
|
|
6864
|
+
return "";
|
|
6865
|
+
const filtered = Object.entries(params)
|
|
6866
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
6867
|
+
.map(([k, v]) => [k, String(v)]);
|
|
6868
|
+
if (filtered.length === 0)
|
|
6869
|
+
return "";
|
|
6870
|
+
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
6871
|
+
}
|
|
6872
|
+
async request(method, endpoint, body, headers) {
|
|
6873
|
+
let res = null;
|
|
6807
6874
|
try {
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6875
|
+
res = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
6876
|
+
method,
|
|
6877
|
+
...this.getRequestOptions(),
|
|
6878
|
+
headers: this.mergeHeaders(this.baseHeaders(), headers),
|
|
6879
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
6880
|
+
});
|
|
6881
|
+
let data;
|
|
6882
|
+
try {
|
|
6883
|
+
data = await res.json();
|
|
6814
6884
|
}
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
if (typeof decoded.exp !== "number" || !Number.isFinite(decoded.exp)) {
|
|
6818
|
-
return false;
|
|
6885
|
+
catch {
|
|
6886
|
+
data = undefined;
|
|
6819
6887
|
}
|
|
6820
|
-
|
|
6821
|
-
return
|
|
6888
|
+
this.setConnectionStatus(true);
|
|
6889
|
+
return {
|
|
6890
|
+
data,
|
|
6891
|
+
status: res.status,
|
|
6892
|
+
headers: res.headers,
|
|
6893
|
+
success: res.ok,
|
|
6894
|
+
connectionError: false,
|
|
6895
|
+
};
|
|
6822
6896
|
}
|
|
6823
6897
|
catch (error) {
|
|
6824
|
-
|
|
6825
|
-
|
|
6898
|
+
const connectionFailed = this.isConnectionError(error);
|
|
6899
|
+
if (connectionFailed) {
|
|
6900
|
+
this.setConnectionStatus(false);
|
|
6901
|
+
this.handleConnectionError(error, endpoint, method);
|
|
6902
|
+
}
|
|
6903
|
+
return {
|
|
6904
|
+
status: res?.status ?? (connectionFailed ? 0 : 500),
|
|
6905
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6906
|
+
headers: res?.headers ?? new Headers(),
|
|
6907
|
+
success: false,
|
|
6908
|
+
data: undefined,
|
|
6909
|
+
connectionError: connectionFailed,
|
|
6910
|
+
};
|
|
6826
6911
|
}
|
|
6827
6912
|
}
|
|
6828
|
-
async
|
|
6829
|
-
const
|
|
6830
|
-
return
|
|
6913
|
+
async get(endpoint, headers, params) {
|
|
6914
|
+
const queryString = this.buildQueryString(params);
|
|
6915
|
+
return this.request("GET", `${endpoint}${queryString}`, undefined, headers);
|
|
6831
6916
|
}
|
|
6832
|
-
async
|
|
6833
|
-
|
|
6834
|
-
if (currentToken && this.isTokenValid(currentToken)) {
|
|
6835
|
-
return currentToken;
|
|
6836
|
-
}
|
|
6837
|
-
await this.helpers.refreshToken();
|
|
6838
|
-
if (authStore.state.globalErrors.auth || !authStore.state.token) {
|
|
6839
|
-
return this.createAuthError(i18n.t("errors.refresh_failed"), "REFRESH_FAILED", true);
|
|
6840
|
-
}
|
|
6841
|
-
return authStore.state.token;
|
|
6917
|
+
async post(endpoint, body, headers) {
|
|
6918
|
+
return this.request("POST", endpoint, body, headers);
|
|
6842
6919
|
}
|
|
6843
|
-
async
|
|
6844
|
-
|
|
6845
|
-
if (typeof token !== "string") {
|
|
6846
|
-
return null;
|
|
6847
|
-
}
|
|
6848
|
-
if (!token) {
|
|
6849
|
-
return null;
|
|
6850
|
-
}
|
|
6851
|
-
try {
|
|
6852
|
-
return jwtDecode(token);
|
|
6853
|
-
}
|
|
6854
|
-
catch (error) {
|
|
6855
|
-
index.captureException(error);
|
|
6856
|
-
return null;
|
|
6857
|
-
}
|
|
6920
|
+
async patch(endpoint, body, headers) {
|
|
6921
|
+
return this.request("PATCH", endpoint, body, headers);
|
|
6858
6922
|
}
|
|
6859
|
-
async
|
|
6860
|
-
|
|
6861
|
-
if (error) {
|
|
6862
|
-
return this.createAuthError(i18n.t("errors.sign_out_failed", { reason: error }), "SIGN_OUT_FAILED", false);
|
|
6863
|
-
}
|
|
6864
|
-
authStore.authStore.reset();
|
|
6865
|
-
return true;
|
|
6923
|
+
async delete(endpoint, headers) {
|
|
6924
|
+
return this.request("DELETE", endpoint, undefined, headers);
|
|
6866
6925
|
}
|
|
6867
|
-
|
|
6868
|
-
|
|
6926
|
+
}
|
|
6927
|
+
|
|
6928
|
+
/**
|
|
6929
|
+
* Browser-specific API client with CORS mode and Sentry error reporting.
|
|
6930
|
+
*/
|
|
6931
|
+
class ApiClient extends BaseApiClient {
|
|
6932
|
+
constructor(baseUrl, apiKey, onConnectionChange) {
|
|
6933
|
+
super({ baseUrl, apiKey, onConnectionChange });
|
|
6869
6934
|
}
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6935
|
+
setConnectionStatus(isConnected) {
|
|
6936
|
+
super.setConnectionStatus(isConnected);
|
|
6937
|
+
unidyStore.unidyState.backendConnected = isConnected;
|
|
6938
|
+
}
|
|
6939
|
+
getRequestOptions() {
|
|
6940
|
+
return {
|
|
6941
|
+
mode: "cors",
|
|
6942
|
+
credentials: "include",
|
|
6943
|
+
};
|
|
6944
|
+
}
|
|
6945
|
+
handleConnectionError(error, endpoint, method) {
|
|
6946
|
+
index.captureException(error, {
|
|
6947
|
+
tags: { error_type: "connection_error" },
|
|
6948
|
+
extra: { endpoint, method },
|
|
6949
|
+
});
|
|
6875
6950
|
}
|
|
6876
6951
|
}
|
|
6877
6952
|
|
|
@@ -6924,16 +6999,24 @@ exports.AuthService = AuthService;
|
|
|
6924
6999
|
exports.BaseApiClient = BaseApiClient;
|
|
6925
7000
|
exports.BaseErrorSchema = BaseErrorSchema;
|
|
6926
7001
|
exports.BaseService = BaseService;
|
|
7002
|
+
exports.ExportFormat = ExportFormat;
|
|
7003
|
+
exports.ExportLinkResponseSchema = ExportLinkResponseSchema;
|
|
6927
7004
|
exports.NewsletterService = NewsletterService;
|
|
6928
7005
|
exports.PaginationMetaSchema = PaginationMetaSchema;
|
|
6929
7006
|
exports.PaginationParamsSchema = PaginationParamsSchema;
|
|
6930
7007
|
exports.ProfileService = ProfileService;
|
|
6931
7008
|
exports.SchemaValidationErrorSchema = SchemaValidationErrorSchema;
|
|
7009
|
+
exports.SubscriptionSchema = SubscriptionSchema;
|
|
7010
|
+
exports.SubscriptionsListResponseSchema = SubscriptionsListResponseSchema;
|
|
6932
7011
|
exports.SubscriptionsService = SubscriptionsService;
|
|
7012
|
+
exports.TicketSchema = TicketSchema;
|
|
7013
|
+
exports.TicketableListParamsSchema = TicketableListParamsSchema;
|
|
7014
|
+
exports.TicketsListResponseSchema = TicketsListResponseSchema;
|
|
6933
7015
|
exports.TicketsService = TicketsService;
|
|
6934
7016
|
exports.UnidyClient = UnidyClient;
|
|
6935
7017
|
exports.UserProfileSchema = UserProfileSchema;
|
|
7018
|
+
exports.clearUrlParam = clearUrlParam;
|
|
6936
7019
|
exports.getUnidyClient = getUnidyClient;
|
|
6937
|
-
//# sourceMappingURL=index-
|
|
7020
|
+
//# sourceMappingURL=index-CpPKy1CZ.js.map
|
|
6938
7021
|
|
|
6939
|
-
//# sourceMappingURL=index-
|
|
7022
|
+
//# sourceMappingURL=index-CpPKy1CZ.js.map
|