@burdenoff/microfe-auth 2026.510.127
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/README.md +12 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/auth/AuthRoot.d.ts +30 -0
- package/dist/auth/AuthRoot.d.ts.map +1 -0
- package/dist/auth/AuthRoot.js +82 -0
- package/dist/auth/AuthRoot.js.map +1 -0
- package/dist/auth/AuthRoutes.d.ts +29 -0
- package/dist/auth/AuthRoutes.d.ts.map +1 -0
- package/dist/auth/AuthRoutes.js +271 -0
- package/dist/auth/AuthRoutes.js.map +1 -0
- package/dist/auth/components/AuthIcons.d.ts +17 -0
- package/dist/auth/components/AuthIcons.d.ts.map +1 -0
- package/dist/auth/components/AuthIcons.js +197 -0
- package/dist/auth/components/AuthIcons.js.map +1 -0
- package/dist/auth/components/AuthLayout.d.ts +17 -0
- package/dist/auth/components/AuthLayout.d.ts.map +1 -0
- package/dist/auth/components/AuthLayout.js +237 -0
- package/dist/auth/components/AuthLayout.js.map +1 -0
- package/dist/auth/components/CaptchaV2.d.ts +16 -0
- package/dist/auth/components/CaptchaV2.d.ts.map +1 -0
- package/dist/auth/components/CaptchaV2.js +47 -0
- package/dist/auth/components/CaptchaV2.js.map +1 -0
- package/dist/auth/components/ConfirmActionDialog.d.ts +16 -0
- package/dist/auth/components/ConfirmActionDialog.d.ts.map +1 -0
- package/dist/auth/components/ConfirmActionDialog.js +68 -0
- package/dist/auth/components/ConfirmActionDialog.js.map +1 -0
- package/dist/auth/components/index.d.ts +4 -0
- package/dist/auth/components/index.d.ts.map +1 -0
- package/dist/auth/components/profile/UserProfileMenu.d.ts +42 -0
- package/dist/auth/components/profile/UserProfileMenu.d.ts.map +1 -0
- package/dist/auth/components/profile/UserProfileMenu.js +91 -0
- package/dist/auth/components/profile/UserProfileMenu.js.map +1 -0
- package/dist/auth/components/workspace/WorkspaceSelector.d.ts +76 -0
- package/dist/auth/components/workspace/WorkspaceSelector.d.ts.map +1 -0
- package/dist/auth/components/workspace/WorkspaceSelector.js +240 -0
- package/dist/auth/components/workspace/WorkspaceSelector.js.map +1 -0
- package/dist/auth/constants/permissions.d.ts +30 -0
- package/dist/auth/constants/permissions.d.ts.map +1 -0
- package/dist/auth/constants/permissions.js +18 -0
- package/dist/auth/constants/permissions.js.map +1 -0
- package/dist/auth/constants/sessionKeys.d.ts +18 -0
- package/dist/auth/constants/sessionKeys.d.ts.map +1 -0
- package/dist/auth/constants/sessionKeys.js +6 -0
- package/dist/auth/constants/sessionKeys.js.map +1 -0
- package/dist/auth/hooks/index.d.ts +18 -0
- package/dist/auth/hooks/index.d.ts.map +1 -0
- package/dist/auth/hooks/index.js +16 -0
- package/dist/auth/hooks/useAccountOperations.d.ts +19 -0
- package/dist/auth/hooks/useAccountOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useAccountOperations.js +52 -0
- package/dist/auth/hooks/useAccountOperations.js.map +1 -0
- package/dist/auth/hooks/useApiKeyOperations.d.ts +22 -0
- package/dist/auth/hooks/useApiKeyOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useApiKeyOperations.js +4 -0
- package/dist/auth/hooks/useAppOperations.d.ts +26 -0
- package/dist/auth/hooks/useAppOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useAppOperations.js +4 -0
- package/dist/auth/hooks/useAuthOperations.d.ts +57 -0
- package/dist/auth/hooks/useAuthOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthOperations.js +236 -0
- package/dist/auth/hooks/useAuthOperations.js.map +1 -0
- package/dist/auth/hooks/useAuthPermissions.d.ts +20 -0
- package/dist/auth/hooks/useAuthPermissions.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthPermissions.js +22 -0
- package/dist/auth/hooks/useAuthPermissions.js.map +1 -0
- package/dist/auth/hooks/useCaptchaV3.d.ts +13 -0
- package/dist/auth/hooks/useCaptchaV3.d.ts.map +1 -0
- package/dist/auth/hooks/useCaptchaV3.js +19 -0
- package/dist/auth/hooks/useCaptchaV3.js.map +1 -0
- package/dist/auth/hooks/useContextSwitcherData.d.ts +106 -0
- package/dist/auth/hooks/useContextSwitcherData.d.ts.map +1 -0
- package/dist/auth/hooks/useContextSwitcherData.js +466 -0
- package/dist/auth/hooks/useContextSwitcherData.js.map +1 -0
- package/dist/auth/hooks/useDelegationOperations.d.ts +25 -0
- package/dist/auth/hooks/useDelegationOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useDelegationOperations.js +4 -0
- package/dist/auth/hooks/useMfaOperations.d.ts +18 -0
- package/dist/auth/hooks/useMfaOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useMfaOperations.js +103 -0
- package/dist/auth/hooks/useMfaOperations.js.map +1 -0
- package/dist/auth/hooks/useMyWorkspaces.d.ts +45 -0
- package/dist/auth/hooks/useMyWorkspaces.d.ts.map +1 -0
- package/dist/auth/hooks/useMyWorkspaces.js +140 -0
- package/dist/auth/hooks/useMyWorkspaces.js.map +1 -0
- package/dist/auth/hooks/useOAuthOperations.d.ts +19 -0
- package/dist/auth/hooks/useOAuthOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useOAuthOperations.js +103 -0
- package/dist/auth/hooks/useOAuthOperations.js.map +1 -0
- package/dist/auth/hooks/usePasswordOperations.d.ts +13 -0
- package/dist/auth/hooks/usePasswordOperations.d.ts.map +1 -0
- package/dist/auth/hooks/usePasswordOperations.js +56 -0
- package/dist/auth/hooks/usePasswordOperations.js.map +1 -0
- package/dist/auth/hooks/useSessionOperations.d.ts +41 -0
- package/dist/auth/hooks/useSessionOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useSessionOperations.js +59 -0
- package/dist/auth/hooks/useSessionOperations.js.map +1 -0
- package/dist/auth/hooks/useSsoOperations.d.ts +65 -0
- package/dist/auth/hooks/useSsoOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useSsoOperations.js +236 -0
- package/dist/auth/hooks/useSsoOperations.js.map +1 -0
- package/dist/auth/hooks/useTokenRefresh.d.ts +56 -0
- package/dist/auth/hooks/useTokenRefresh.d.ts.map +1 -0
- package/dist/auth/hooks/useTokenRefresh.js +53 -0
- package/dist/auth/hooks/useTokenRefresh.js.map +1 -0
- package/dist/auth/hooks/useUserOperations.d.ts +32 -0
- package/dist/auth/hooks/useUserOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useUserOperations.js +100 -0
- package/dist/auth/hooks/useUserOperations.js.map +1 -0
- package/dist/auth/hooks/useWorkspaceOperations.d.ts +35 -0
- package/dist/auth/hooks/useWorkspaceOperations.d.ts.map +1 -0
- package/dist/auth/hooks/useWorkspaceOperations.js +35 -0
- package/dist/auth/hooks/useWorkspaceOperations.js.map +1 -0
- package/dist/auth/hooks/useWorkspaceToken.d.ts +56 -0
- package/dist/auth/hooks/useWorkspaceToken.d.ts.map +1 -0
- package/dist/auth/hooks/useWorkspaceToken.js +94 -0
- package/dist/auth/hooks/useWorkspaceToken.js.map +1 -0
- package/dist/auth/index.d.ts +63 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +18 -0
- package/dist/auth/pages/ApiKeysPage.d.ts +5 -0
- package/dist/auth/pages/ApiKeysPage.d.ts.map +1 -0
- package/dist/auth/pages/AppsPage.d.ts +5 -0
- package/dist/auth/pages/AppsPage.d.ts.map +1 -0
- package/dist/auth/pages/AuditLogPage.d.ts +5 -0
- package/dist/auth/pages/AuditLogPage.d.ts.map +1 -0
- package/dist/auth/pages/AuditLogPage.js +129 -0
- package/dist/auth/pages/AuditLogPage.js.map +1 -0
- package/dist/auth/pages/DelegationsPage.d.ts +5 -0
- package/dist/auth/pages/DelegationsPage.d.ts.map +1 -0
- package/dist/auth/pages/EmailVerifyPage.d.ts +5 -0
- package/dist/auth/pages/EmailVerifyPage.d.ts.map +1 -0
- package/dist/auth/pages/EmailVerifyPage.js +166 -0
- package/dist/auth/pages/EmailVerifyPage.js.map +1 -0
- package/dist/auth/pages/LoginPage.d.ts +6 -0
- package/dist/auth/pages/LoginPage.d.ts.map +1 -0
- package/dist/auth/pages/LoginPage.js +575 -0
- package/dist/auth/pages/LoginPage.js.map +1 -0
- package/dist/auth/pages/MagicLinkPage.d.ts +6 -0
- package/dist/auth/pages/MagicLinkPage.d.ts.map +1 -0
- package/dist/auth/pages/MagicLinkPage.js +219 -0
- package/dist/auth/pages/MagicLinkPage.js.map +1 -0
- package/dist/auth/pages/MfaSetupPage.d.ts +5 -0
- package/dist/auth/pages/MfaSetupPage.d.ts.map +1 -0
- package/dist/auth/pages/MfaSetupPage.js +341 -0
- package/dist/auth/pages/MfaSetupPage.js.map +1 -0
- package/dist/auth/pages/MfaVerifyPage.d.ts +7 -0
- package/dist/auth/pages/MfaVerifyPage.d.ts.map +1 -0
- package/dist/auth/pages/MfaVerifyPage.js +189 -0
- package/dist/auth/pages/MfaVerifyPage.js.map +1 -0
- package/dist/auth/pages/OAuthCallbackPage.d.ts +7 -0
- package/dist/auth/pages/OAuthCallbackPage.d.ts.map +1 -0
- package/dist/auth/pages/OAuthCallbackPage.js +100 -0
- package/dist/auth/pages/OAuthCallbackPage.js.map +1 -0
- package/dist/auth/pages/PasswordResetPage.d.ts +6 -0
- package/dist/auth/pages/PasswordResetPage.d.ts.map +1 -0
- package/dist/auth/pages/PasswordResetPage.js +352 -0
- package/dist/auth/pages/PasswordResetPage.js.map +1 -0
- package/dist/auth/pages/ReactivatePage.d.ts +6 -0
- package/dist/auth/pages/ReactivatePage.d.ts.map +1 -0
- package/dist/auth/pages/ReactivatePage.js +217 -0
- package/dist/auth/pages/ReactivatePage.js.map +1 -0
- package/dist/auth/pages/RegisterPage.d.ts +5 -0
- package/dist/auth/pages/RegisterPage.d.ts.map +1 -0
- package/dist/auth/pages/RegisterPage.js +439 -0
- package/dist/auth/pages/RegisterPage.js.map +1 -0
- package/dist/auth/pages/SSORelayCallbackPage.d.ts +8 -0
- package/dist/auth/pages/SSORelayCallbackPage.d.ts.map +1 -0
- package/dist/auth/pages/SSORelayCallbackPage.js +48 -0
- package/dist/auth/pages/SSORelayCallbackPage.js.map +1 -0
- package/dist/auth/pages/SSORelayPage.d.ts +18 -0
- package/dist/auth/pages/SSORelayPage.d.ts.map +1 -0
- package/dist/auth/pages/SSORelayPage.js +134 -0
- package/dist/auth/pages/SSORelayPage.js.map +1 -0
- package/dist/auth/pages/SecurityPage.d.ts +5 -0
- package/dist/auth/pages/SecurityPage.d.ts.map +1 -0
- package/dist/auth/pages/SecurityPage.js +587 -0
- package/dist/auth/pages/SecurityPage.js.map +1 -0
- package/dist/auth/pages/SessionBridgePage.d.ts +14 -0
- package/dist/auth/pages/SessionBridgePage.d.ts.map +1 -0
- package/dist/auth/pages/SessionBridgePage.js +231 -0
- package/dist/auth/pages/SessionBridgePage.js.map +1 -0
- package/dist/auth/pages/SessionsPage.d.ts +5 -0
- package/dist/auth/pages/SessionsPage.d.ts.map +1 -0
- package/dist/auth/pages/SessionsPage.js +258 -0
- package/dist/auth/pages/SessionsPage.js.map +1 -0
- package/dist/auth/pages/SsoCallbackPage.d.ts +8 -0
- package/dist/auth/pages/SsoCallbackPage.d.ts.map +1 -0
- package/dist/auth/pages/SsoCallbackPage.js +188 -0
- package/dist/auth/pages/SsoCallbackPage.js.map +1 -0
- package/dist/auth/pages/SsoConfigPage.d.ts +6 -0
- package/dist/auth/pages/SsoConfigPage.d.ts.map +1 -0
- package/dist/auth/pages/SsoConfigPage.js +1144 -0
- package/dist/auth/pages/SsoConfigPage.js.map +1 -0
- package/dist/auth/pages/SsoLoginPage.d.ts +7 -0
- package/dist/auth/pages/SsoLoginPage.d.ts.map +1 -0
- package/dist/auth/pages/SsoLoginPage.js +236 -0
- package/dist/auth/pages/SsoLoginPage.js.map +1 -0
- package/dist/auth/pages/UserDetailsPage.d.ts +11 -0
- package/dist/auth/pages/UserDetailsPage.d.ts.map +1 -0
- package/dist/auth/pages/UserDetailsPage.js +338 -0
- package/dist/auth/pages/UserDetailsPage.js.map +1 -0
- package/dist/auth/pages/UserProfilePage.d.ts +5 -0
- package/dist/auth/pages/UserProfilePage.d.ts.map +1 -0
- package/dist/auth/pages/UserProfilePage.js +445 -0
- package/dist/auth/pages/UserProfilePage.js.map +1 -0
- package/dist/auth/pages/UsersPage.d.ts +5 -0
- package/dist/auth/pages/UsersPage.d.ts.map +1 -0
- package/dist/auth/pages/UsersPage.js +899 -0
- package/dist/auth/pages/UsersPage.js.map +1 -0
- package/dist/auth/providers/AuthProvider.d.ts +18 -0
- package/dist/auth/providers/AuthProvider.d.ts.map +1 -0
- package/dist/auth/providers/AuthProvider.js +36 -0
- package/dist/auth/providers/AuthProvider.js.map +1 -0
- package/dist/auth/providers/CaptchaProvider.d.ts +13 -0
- package/dist/auth/providers/CaptchaProvider.d.ts.map +1 -0
- package/dist/auth/providers/CaptchaProvider.js +21 -0
- package/dist/auth/providers/CaptchaProvider.js.map +1 -0
- package/dist/auth/store/authStore.d.ts +91 -0
- package/dist/auth/store/authStore.d.ts.map +1 -0
- package/dist/auth/store/authStore.js +314 -0
- package/dist/auth/store/authStore.js.map +1 -0
- package/dist/auth/types/index.d.ts +636 -0
- package/dist/auth/types/index.d.ts.map +1 -0
- package/dist/auth/utils/captchaConfig.d.ts +4 -0
- package/dist/auth/utils/captchaConfig.d.ts.map +1 -0
- package/dist/auth/utils/captchaConfig.js +13 -0
- package/dist/auth/utils/captchaConfig.js.map +1 -0
- package/dist/auth/utils/formatters.d.ts +37 -0
- package/dist/auth/utils/formatters.d.ts.map +1 -0
- package/dist/auth/utils/formatters.js +48 -0
- package/dist/auth/utils/formatters.js.map +1 -0
- package/dist/auth/utils/gatewayBaseUrls.d.ts +6 -0
- package/dist/auth/utils/gatewayBaseUrls.d.ts.map +1 -0
- package/dist/auth/utils/gatewayBaseUrls.js +18 -0
- package/dist/auth/utils/gatewayBaseUrls.js.map +1 -0
- package/dist/auth/utils/index.d.ts +3 -0
- package/dist/auth/utils/index.d.ts.map +1 -0
- package/dist/auth/utils/validation.d.ts +30 -0
- package/dist/auth/utils/validation.d.ts.map +1 -0
- package/dist/auth/utils/validation.js +15 -0
- package/dist/auth/utils/validation.js.map +1 -0
- package/dist/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +2978 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-operations.js +944 -0
- package/dist/generated/global-operations.js.map +1 -0
- package/dist/generated/global-types.d.ts +21253 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-types.d.ts +55214 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/microfe-auth.css +3 -0
- package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +70 -0
- package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
- package/dist/node_modules/object-assign/index.js +41 -0
- package/dist/node_modules/object-assign/index.js.map +1 -0
- package/dist/node_modules/prop-types/checkPropTypes.js +46 -0
- package/dist/node_modules/prop-types/checkPropTypes.js.map +1 -0
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js +49 -0
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js.map +1 -0
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js +272 -0
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js.map +1 -0
- package/dist/node_modules/prop-types/index.js +16 -0
- package/dist/node_modules/prop-types/index.js.map +1 -0
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js +10 -0
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js.map +1 -0
- package/dist/node_modules/prop-types/lib/has.js +10 -0
- package/dist/node_modules/prop-types/lib/has.js.map +1 -0
- package/dist/node_modules/qrcode.react/lib/esm/index.js +959 -0
- package/dist/node_modules/qrcode.react/lib/esm/index.js.map +1 -0
- package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js +114 -0
- package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/index.js +8 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/index.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js +20 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js +148 -0
- package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js.map +1 -0
- package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js +445 -0
- package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js.map +1 -0
- package/dist/node_modules/react-is/cjs/react-is.development.js +84 -0
- package/dist/node_modules/react-is/cjs/react-is.development.js.map +1 -0
- package/dist/node_modules/react-is/cjs/react-is.production.min.js +64 -0
- package/dist/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
- package/dist/node_modules/react-is/index.js +12 -0
- package/dist/node_modules/react-is/index.js.map +1 -0
- package/dist/shared/hooks/index.d.ts +7 -0
- package/dist/shared/hooks/index.d.ts.map +1 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/types/index.d.ts +109 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/utils/nativeBridge.d.ts +3 -0
- package/dist/utils/nativeBridge.d.ts.map +1 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +114 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSsoOperations.js","names":[],"sources":["../../../src/auth/hooks/useSsoOperations.ts"],"sourcesContent":["import { useMutation, useQuery } from \"@apollo/client/react\";\nimport { useAuthStore } from \"../store/authStore\";\nimport type { AuthResult, SSOConfig, User } from \"../types\";\nimport {\n OIDC_CODE_VERIFIER,\n OIDC_STATE,\n OIDC_NONCE,\n OIDC_TENANT_ID,\n OIDC_FLOW,\n OIDC_REDIRECT,\n} from \"../constants/sessionKeys\";\n\nimport {\n AuthenticateSamlDocument,\n GenerateSamlRequestDocument,\n AuthenticateOidcDocument,\n GenerateOidcAuthUrlDocument,\n GetSsoConfigDocument,\n GetOidcConfigDocument,\n SaveSsoConfigDocument,\n DeleteSsoConfigDocument,\n} from \"../../generated/global-operations\";\n// =============================================================================\n// GraphQL Response Types (Apollo Client 4.x)\n// =============================================================================\n\ninterface GetSSOConfigResponse {\n getSSOConfig: SSOConfig | null;\n}\n\ninterface GetSSOConfigVariables {\n tenantId: string;\n}\n\ninterface SaveSSOConfigResponse {\n saveSSOConfig: SSOConfig;\n}\n\ninterface SaveSSOConfigVariables {\n tenantId: string;\n input: SSOConfigInput;\n}\n\ninterface DeleteSSOConfigResponse {\n deleteSSOConfig: boolean;\n}\n\ninterface DeleteSSOConfigVariables {\n tenantId: string;\n}\n\ninterface GenerateSAMLRequestResponse {\n generateSAMLRequest: SAMLRequestResult;\n}\n\ninterface GenerateSAMLRequestVariables {\n tenantId: string;\n relayState?: string;\n}\n\ninterface AuthenticateSAMLResponse {\n authenticateSAML: AuthResult;\n}\n\ninterface AuthenticateSAMLVariables {\n input: {\n samlResponse: string;\n relayState?: string;\n tenantId?: string;\n };\n}\n\ninterface GetOIDCConfigResponse {\n getOIDCConfig: OIDCConfig | null;\n}\n\ninterface GenerateOIDCAuthUrlResponse {\n generateOIDCAuthUrl: ExternalOIDCAuthUrlResult;\n}\n\ninterface GenerateOIDCAuthUrlVariables {\n tenantId: string;\n state?: string;\n}\n\ninterface AuthenticateOIDCPayload {\n accessToken: string;\n refreshToken?: string;\n expiresIn: number;\n user: User;\n}\n\ninterface AuthenticateOIDCResponse {\n authenticateOIDC: AuthenticateOIDCPayload;\n}\n\ninterface AuthenticateOIDCVariables {\n input: {\n tenantId: string;\n code: string;\n state: string;\n codeVerifier: string;\n nonce?: string | null;\n };\n}\n\n// =============================================================================\n// GraphQL Operations\n// =============================================================================\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SSOConfigInput {\n entityId: string;\n ssoUrl: string;\n sloUrl?: string;\n certificate: string;\n enabled?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SAMLRequestResult {\n requestId: string;\n ssoUrl: string;\n samlRequest: string;\n}\n\nexport interface ExternalOIDCAuthUrlResult {\n authUrl: string;\n state: string;\n nonce: string;\n codeVerifier: string;\n relayState?: string;\n}\n\nexport interface OIDCConfig {\n issuer: string;\n authorizationEndpoint: string;\n tokenEndpoint: string;\n userinfoEndpoint: string;\n jwksUri: string;\n registrationEndpoint?: string;\n scopesSupported: string[];\n responseTypesSupported: string[];\n grantTypesSupported: string[];\n}\n\ninterface GraphQLErrorLike {\n message?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getGraphQLErrors(error: unknown): GraphQLErrorLike[] {\n if (!isRecord(error)) return [];\n const graphQLErrors = error.graphQLErrors;\n if (!Array.isArray(graphQLErrors)) return [];\n return graphQLErrors.filter((item): item is GraphQLErrorLike =>\n isRecord(item),\n );\n}\n\nfunction getErrorMessage(error: unknown, fallback: string): string {\n const graphQLError = getGraphQLErrors(error)[0];\n if (graphQLError?.message) return graphQLError.message;\n if (error instanceof Error) return error.message;\n if (isRecord(error) && typeof error.message === \"string\") {\n return error.message;\n }\n return fallback;\n}\n\n// =============================================================================\n// Hook\n// =============================================================================\n\n/**\n * Hook for SSO/SAML operations\n */\nexport function useSsoOperations(tenantId?: string) {\n const [generateSamlRequestMutation, { loading: generatingRequest }] =\n useMutation<GenerateSAMLRequestResponse, GenerateSAMLRequestVariables>(\n GenerateSamlRequestDocument,\n );\n const [authenticateSamlMutation, { loading: authenticating }] = useMutation<\n AuthenticateSAMLResponse,\n AuthenticateSAMLVariables\n >(AuthenticateSamlDocument);\n const [saveSsoConfigMutation, { loading: saving }] = useMutation<\n SaveSSOConfigResponse,\n SaveSSOConfigVariables\n >(SaveSsoConfigDocument);\n const [deleteSsoConfigMutation, { loading: deleting }] = useMutation<\n DeleteSSOConfigResponse,\n DeleteSSOConfigVariables\n >(DeleteSsoConfigDocument);\n const [generateOidcAuthUrlMutation, { loading: generatingOidcUrl }] =\n useMutation<GenerateOIDCAuthUrlResponse, GenerateOIDCAuthUrlVariables>(\n GenerateOidcAuthUrlDocument,\n );\n const [authenticateOidcMutation, { loading: authenticatingOidc }] =\n useMutation<AuthenticateOIDCResponse, AuthenticateOIDCVariables>(\n AuthenticateOidcDocument,\n );\n\n // Get SSO config for tenant\n const {\n data: ssoConfigData,\n loading: loadingConfig,\n refetch: refetchConfig,\n } = useQuery<GetSSOConfigResponse, GetSSOConfigVariables>(\n GetSsoConfigDocument,\n {\n variables: { tenantId: tenantId || \"\" },\n skip: !tenantId,\n },\n );\n\n // Get OIDC discovery info (for our OIDC provider)\n const { data: oidcConfigData, loading: loadingOidc } =\n useQuery<GetOIDCConfigResponse>(GetOidcConfigDocument, {\n skip: false, // Always fetch OIDC config\n });\n\n /**\n * Initiate SP-initiated SAML login\n * Redirects user to IdP with SAML AuthnRequest\n */\n const initiateSsoLogin = async (\n targetTenantId: string,\n relayState?: string,\n ): Promise<void> => {\n try {\n const { data } = await generateSamlRequestMutation({\n variables: { tenantId: targetTenantId, relayState },\n });\n\n // Check if data exists\n if (!data || !data.generateSAMLRequest) {\n throw new Error(\n \"SAML SSO is not configured for this tenant. Please contact your administrator or use email/password login.\",\n );\n }\n\n const result = data.generateSAMLRequest;\n\n // Build the IdP redirect URL with SAML request\n const params = new URLSearchParams({\n SAMLRequest: result.samlRequest,\n });\n if (relayState) {\n params.append(\"RelayState\", relayState);\n }\n\n // Redirect to IdP SSO URL\n window.location.href = `${result.ssoUrl}?${params.toString()}`;\n } catch (error: unknown) {\n // Extract error message from Apollo error or regular error\n const message = getErrorMessage(\n error,\n \"Failed to initiate SAML SSO login\",\n );\n\n console.error(\"Failed to initiate SSO login:\", message);\n throw new Error(message);\n }\n };\n\n /**\n * Handle SAML callback from IdP\n * Called when IdP redirects back with SAML Response\n */\n const handleSamlCallback = async (\n samlResponse: string,\n relayState?: string,\n ): Promise<AuthResult> => {\n const store = useAuthStore.getState();\n const targetTenantId =\n tenantId || sessionStorage.getItem(OIDC_TENANT_ID) || undefined;\n\n try {\n store.setLoading(true);\n store.setError(null);\n\n const { data, error } = await authenticateSamlMutation({\n variables: {\n input: {\n samlResponse,\n relayState,\n tenantId: targetTenantId,\n },\n },\n });\n\n if (!data?.authenticateSAML) {\n const errMsg =\n error?.message ?? \"SAML authentication failed. Please try again.\";\n throw new Error(errMsg);\n }\n\n const result = data.authenticateSAML;\n\n if (result.success && result.user && result.token) {\n store.setUser(result.user);\n store.setAuthTokens(result.token, result.refreshToken || \"\");\n store.setAuthenticated(true);\n } else if (result.error) {\n store.setError(result.error);\n }\n\n return result;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"SAML authentication failed\";\n store.setError(message);\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Initiate external OIDC login (Azure AD, Google, etc.)\n * Redirects user to external IdP for authentication\n */\n const initiateExternalOidcLogin = async (\n targetTenantId: string,\n redirectPath?: string,\n ): Promise<void> => {\n try {\n const { data } = await generateOidcAuthUrlMutation({\n variables: { tenantId: targetTenantId, state: redirectPath },\n });\n\n // Check if data exists\n if (!data || !data.generateOIDCAuthUrl) {\n throw new Error(\n \"SSO is not configured for this tenant. Please contact your administrator or use email/password login.\",\n );\n }\n\n const result = data.generateOIDCAuthUrl;\n\n // Store PKCE values for token exchange\n sessionStorage.setItem(OIDC_CODE_VERIFIER, result.codeVerifier);\n sessionStorage.setItem(OIDC_STATE, result.state); // Secure random state for CSRF protection\n sessionStorage.setItem(OIDC_NONCE, result.nonce);\n sessionStorage.setItem(OIDC_TENANT_ID, targetTenantId);\n sessionStorage.setItem(OIDC_FLOW, \"external\"); // Mark as external OIDC flow\n // Store relay state (redirect path) separately from security state\n sessionStorage.setItem(\n \"oidc_redirect\",\n result.relayState || redirectPath || \"/dashboard\",\n );\n\n // Redirect to external IdP\n window.location.href = result.authUrl;\n } catch (error: unknown) {\n // Extract error message from Apollo error or regular error\n const message = getErrorMessage(\n error,\n \"Failed to initiate OIDC SSO login\",\n );\n\n console.error(\"Failed to initiate external OIDC login:\", message);\n throw new Error(message);\n }\n };\n\n /**\n * Handle external OIDC callback\n * Called when external IdP redirects back with authorization code\n */\n const handleExternalOidcCallback = async (\n code: string,\n state: string,\n ): Promise<AuthResult> => {\n const store = useAuthStore.getState();\n\n try {\n store.setLoading(true);\n store.setError(null);\n\n // Verify state\n const storedState = sessionStorage.getItem(OIDC_STATE);\n\n if (state !== storedState) {\n throw new Error(\n `Invalid state parameter. Possible CSRF attack. Expected: ${storedState?.substring(0, 10)}..., Got: ${state.substring(0, 10)}...`,\n );\n }\n\n const codeVerifier = sessionStorage.getItem(OIDC_CODE_VERIFIER);\n const nonce = sessionStorage.getItem(OIDC_NONCE);\n const targetTenantId =\n sessionStorage.getItem(OIDC_TENANT_ID) || \"default\";\n\n if (!codeVerifier) {\n throw new Error(\n \"Code verifier not found. Please restart the login flow.\",\n );\n }\n\n const result = await authenticateOidcMutation({\n variables: {\n input: {\n tenantId: targetTenantId,\n code,\n state,\n codeVerifier,\n nonce,\n },\n },\n });\n\n const { data } = result;\n if (!data) {\n throw new Error(\"No data returned from authenticateOIDC mutation\");\n }\n\n const authPayload = data.authenticateOIDC;\n\n // Get redirect path before cleanup\n const redirectPath =\n sessionStorage.getItem(OIDC_REDIRECT) || \"/dashboard\";\n\n // Clean up session storage\n sessionStorage.removeItem(OIDC_CODE_VERIFIER);\n sessionStorage.removeItem(OIDC_STATE);\n sessionStorage.removeItem(OIDC_NONCE);\n sessionStorage.removeItem(OIDC_TENANT_ID);\n sessionStorage.removeItem(OIDC_FLOW);\n sessionStorage.removeItem(OIDC_REDIRECT);\n\n if (authPayload.user && authPayload.accessToken) {\n store.setUser(authPayload.user);\n store.setAuthTokens(\n authPayload.accessToken,\n authPayload.refreshToken || \"\",\n );\n store.setAuthenticated(true);\n\n return {\n success: true,\n user: authPayload.user,\n token: authPayload.accessToken,\n refreshToken: authPayload.refreshToken,\n expiresIn: authPayload.expiresIn,\n redirectPath,\n };\n }\n\n return { success: false, error: \"Authentication failed\", redirectPath };\n } catch (error) {\n console.error(\"[OIDC Callback] Error:\", error);\n\n const message =\n error instanceof Error ? error.message : \"OIDC authentication failed\";\n store.setError(message);\n\n // Clean up on error\n sessionStorage.removeItem(OIDC_CODE_VERIFIER);\n sessionStorage.removeItem(OIDC_STATE);\n sessionStorage.removeItem(OIDC_NONCE);\n sessionStorage.removeItem(OIDC_TENANT_ID);\n sessionStorage.removeItem(OIDC_FLOW);\n sessionStorage.removeItem(OIDC_REDIRECT);\n\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Check if the current callback is from external OIDC flow\n * Checks for multiple indicators to be robust\n */\n const isExternalOidcCallback = (): boolean => {\n const hasFlowFlag = sessionStorage.getItem(OIDC_FLOW) === \"external\";\n const hasTenantId = !!sessionStorage.getItem(OIDC_TENANT_ID);\n const hasCodeVerifier = !!sessionStorage.getItem(OIDC_CODE_VERIFIER);\n\n // Return true if we have the flow flag OR if we have both tenant ID and code verifier\n return hasFlowFlag || (hasTenantId && hasCodeVerifier);\n };\n\n /**\n * Save SSO configuration for tenant\n */\n const saveSsoConfig = async (\n configOrTenantId: SSOConfigInput | string,\n config?: SSOConfigInput,\n ): Promise<SSOConfig> => {\n // Support both old (tenantId, config) and new (config) signatures\n const targetTenantId =\n typeof configOrTenantId === \"string\" ? configOrTenantId : tenantId || \"\";\n const finalConfig =\n typeof configOrTenantId === \"string\" ? config! : configOrTenantId;\n\n try {\n const { data, error } = await saveSsoConfigMutation({\n variables: { tenantId: targetTenantId, input: finalConfig },\n });\n await refetchConfig();\n if (!data?.saveSSOConfig) {\n throw new Error(error?.message ?? \"Failed to save SSO config\");\n }\n return data.saveSSOConfig;\n } catch (error) {\n console.error(\"Failed to save SSO config:\", error);\n throw error;\n }\n };\n\n /**\n * Delete SSO configuration for tenant\n */\n const deleteSsoConfig = async (targetTenantId?: string): Promise<boolean> => {\n const finalTenantId = targetTenantId || tenantId || \"\";\n\n try {\n const { data, error } = await deleteSsoConfigMutation({\n variables: { tenantId: finalTenantId },\n });\n await refetchConfig();\n if (data?.deleteSSOConfig == null) {\n throw new Error(error?.message ?? \"Failed to delete SSO config\");\n }\n return data.deleteSSOConfig;\n } catch (error) {\n console.error(\"Failed to delete SSO config:\", error);\n throw error;\n }\n };\n\n /**\n * Get OIDC authorization URL for OAuth login (async for PKCE SHA-256)\n */\n const getOidcAuthUrl = async (\n clientId: string,\n redirectUri: string,\n scopes: string[] = [\"openid\", \"profile\", \"email\"],\n ): Promise<string> => {\n const config = oidcConfigData?.getOIDCConfig;\n if (!config) {\n throw new Error(\"OIDC configuration not available\");\n }\n\n // Generate PKCE code verifier and challenge (async for SHA-256)\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n // Store verifier in sessionStorage for token exchange\n sessionStorage.setItem(OIDC_CODE_VERIFIER, codeVerifier);\n sessionStorage.setItem(OIDC_STATE, state);\n\n const params = new URLSearchParams({\n response_type: \"code\",\n client_id: clientId,\n redirect_uri: redirectUri,\n scope: scopes.join(\" \"),\n state,\n code_challenge: codeChallenge,\n code_challenge_method: \"S256\",\n });\n\n return `${config.authorizationEndpoint}?${params.toString()}`;\n };\n\n /**\n * Exchange OIDC authorization code for tokens\n */\n const exchangeOidcCode = async (\n code: string,\n clientId: string,\n redirectUri: string,\n ): Promise<AuthResult> => {\n const config = oidcConfigData?.getOIDCConfig;\n if (!config) {\n throw new Error(\"OIDC configuration not available\");\n }\n\n const store = useAuthStore.getState();\n const codeVerifier = sessionStorage.getItem(OIDC_CODE_VERIFIER);\n\n if (!codeVerifier) {\n throw new Error(\n \"Code verifier not found. Please restart the login flow.\",\n );\n }\n\n try {\n store.setLoading(true);\n store.setError(null);\n\n // Exchange code for tokens at the OIDC token endpoint\n const response = await fetch(config.tokenEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n code_verifier: codeVerifier,\n }),\n });\n\n const tokenResponse = await response.json();\n\n if (!response.ok) {\n throw new Error(\n tokenResponse.error_description ||\n tokenResponse.error ||\n \"Token exchange failed\",\n );\n }\n\n // Clear PKCE data from session storage\n sessionStorage.removeItem(OIDC_CODE_VERIFIER);\n sessionStorage.removeItem(OIDC_STATE);\n\n // Get user info from userinfo endpoint\n const userinfoResponse = await fetch(config.userinfoEndpoint, {\n headers: {\n Authorization: `Bearer ${tokenResponse.access_token}`,\n },\n });\n\n const userinfo = await userinfoResponse.json();\n\n // Build AuthResult from OIDC response\n const now = new Date().toISOString();\n const result: AuthResult = {\n success: true,\n token: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresIn: tokenResponse.expires_in,\n user: {\n id: userinfo.sub,\n email: userinfo.email,\n username: userinfo.preferred_username || userinfo.email,\n emailVerified: userinfo.email_verified ?? true,\n firstName: userinfo.given_name,\n lastName: userinfo.family_name,\n name: userinfo.name,\n role: \"MEMBER\",\n status: \"ACTIVE\",\n mfaEnabled: false,\n createdAt: now,\n updatedAt: now,\n },\n };\n\n if (result.user && result.token) {\n store.setUser(result.user);\n store.setAuthTokens(result.token, result.refreshToken || \"\");\n store.setAuthenticated(true);\n }\n\n return result;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"OIDC authentication failed\";\n store.setError(message);\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Validate OIDC state parameter\n */\n const validateOidcState = (state: string): boolean => {\n const storedState = sessionStorage.getItem(OIDC_STATE);\n return storedState === state;\n };\n\n return {\n // SSO/SAML operations\n initiateSsoLogin,\n handleSamlCallback,\n saveSsoConfig,\n deleteSsoConfig,\n\n // OIDC operations (our OIDC provider)\n getOidcAuthUrl,\n exchangeOidcCode,\n validateOidcState,\n\n // External OIDC operations (Azure AD, Google, etc.)\n initiateExternalOidcLogin,\n handleExternalOidcCallback,\n isExternalOidcCallback,\n\n // Data\n ssoConfig: ssoConfigData?.getSSOConfig ?? undefined,\n oidcConfig: oidcConfigData?.getOIDCConfig ?? undefined,\n\n // Loading states\n isLoading:\n loadingConfig ||\n loadingOidc ||\n generatingRequest ||\n authenticating ||\n saving ||\n deleting ||\n generatingOidcUrl ||\n authenticatingOidc,\n isGeneratingRequest: generatingRequest,\n isAuthenticating: authenticating || authenticatingOidc,\n isSaving: saving,\n isDeleting: deleting,\n isGeneratingOidcUrl: generatingOidcUrl,\n\n // Refetch\n refetchConfig,\n };\n}\n\n// =============================================================================\n// PKCE Helpers\n// =============================================================================\n\n/**\n * Generate random code verifier for PKCE\n */\nfunction generateCodeVerifier(): string {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n return base64UrlEncode(array);\n}\n\n/**\n * Generate code challenge from verifier using SHA-256 (S256 method)\n * Uses Web Crypto API for secure hashing\n */\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n\n // Use SubtleCrypto for SHA-256 hash\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = new Uint8Array(hashBuffer);\n\n // Base64 URL encode the hash\n return base64UrlEncode(hashArray);\n}\n\n/**\n * Generate random state for CSRF protection\n */\nfunction generateState(): string {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n return base64UrlEncode(array);\n}\n\n/**\n * Base64 URL encode\n */\nfunction base64UrlEncode(array: Uint8Array): string {\n const base64 = btoa(String.fromCharCode(...array));\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automatic workspace token refresh hook
|
|
3
|
+
*
|
|
4
|
+
* Monitors the workspace token and automatically refreshes it
|
|
5
|
+
* 5 minutes before expiry. This ensures uninterrupted access to
|
|
6
|
+
* workspace resources.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```tsx
|
|
10
|
+
* // In your root App component
|
|
11
|
+
* function App() {
|
|
12
|
+
* useTokenRefresh({
|
|
13
|
+
* workspaceAuthServiceUrl: 'http://localhost:3730/graphql',
|
|
14
|
+
* refreshBeforeExpiry: 5 * 60 * 1000, // 5 minutes
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* return <AppContent />;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export interface UseTokenRefreshOptions {
|
|
22
|
+
/**
|
|
23
|
+
* URL of workspace auth service GraphQL endpoint
|
|
24
|
+
* Default: http://localhost:3730/graphql
|
|
25
|
+
*/
|
|
26
|
+
workspaceAuthServiceUrl?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Time before expiry to refresh token (in milliseconds)
|
|
29
|
+
* Default: 5 minutes (300000ms)
|
|
30
|
+
*/
|
|
31
|
+
refreshBeforeExpiry?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Enable/disable auto-refresh
|
|
34
|
+
* Default: true
|
|
35
|
+
*/
|
|
36
|
+
enabled?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Callback when token refresh succeeds
|
|
39
|
+
*/
|
|
40
|
+
onRefreshSuccess?: (token: string) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Callback when token refresh fails
|
|
43
|
+
*/
|
|
44
|
+
onRefreshError?: (error: Error) => void;
|
|
45
|
+
}
|
|
46
|
+
export declare function useTokenRefresh(options?: UseTokenRefreshOptions): {
|
|
47
|
+
/**
|
|
48
|
+
* Manually trigger a token refresh
|
|
49
|
+
*/
|
|
50
|
+
manualRefresh: () => Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if auto-refresh is currently scheduled
|
|
53
|
+
*/
|
|
54
|
+
isScheduled: boolean;
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=useTokenRefresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTokenRefresh.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/useTokenRefresh.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE3C;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACzC;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B;IAyGhE;;OAEG;;IAGH;;OAEG;;EAGN"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useAuthStore as e } from "../store/authStore.js";
|
|
2
|
+
import { useWorkspaceToken as t } from "./useWorkspaceToken.js";
|
|
3
|
+
import { useEffect as n, useRef as r } from "react";
|
|
4
|
+
//#region src/auth/hooks/useTokenRefresh.ts
|
|
5
|
+
function i(i = {}) {
|
|
6
|
+
let { workspaceAuthServiceUrl: a = "http://localhost:3730/graphql", refreshBeforeExpiry: o = 300 * 1e3, enabled: s = !0, onRefreshSuccess: c, onRefreshError: l } = i, { workspaceToken: u } = e(), { refreshToken: d, getTimeUntilExpiry: f, isTokenExpired: p } = t({ workspaceGatewayUrl: a }), m = r(null);
|
|
7
|
+
return n(() => {
|
|
8
|
+
if (m.current &&= (clearTimeout(m.current), null), !s || !u) return;
|
|
9
|
+
if (p(u)) {
|
|
10
|
+
console.warn("[useTokenRefresh] Token is already expired, triggering immediate refresh"), d().then((e) => {
|
|
11
|
+
c?.(e);
|
|
12
|
+
}).catch((e) => {
|
|
13
|
+
console.error("[useTokenRefresh] Failed to refresh expired token:", e), l?.(e);
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let e = f(u) - o;
|
|
18
|
+
if (e <= 0) {
|
|
19
|
+
d().then((e) => {
|
|
20
|
+
c?.(e);
|
|
21
|
+
}).catch((e) => {
|
|
22
|
+
console.error("[useTokenRefresh] Failed to refresh token (immediate):", e), l?.(e);
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
return m.current = setTimeout(async () => {
|
|
27
|
+
try {
|
|
28
|
+
let e = await d();
|
|
29
|
+
c?.(e);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.error("[useTokenRefresh] Token refresh failed:", e), l?.(e);
|
|
32
|
+
}
|
|
33
|
+
}, e), () => {
|
|
34
|
+
m.current &&= (clearTimeout(m.current), null);
|
|
35
|
+
};
|
|
36
|
+
}, [
|
|
37
|
+
u,
|
|
38
|
+
s,
|
|
39
|
+
o,
|
|
40
|
+
d,
|
|
41
|
+
f,
|
|
42
|
+
p,
|
|
43
|
+
c,
|
|
44
|
+
l
|
|
45
|
+
]), {
|
|
46
|
+
manualRefresh: d,
|
|
47
|
+
isScheduled: m.current !== null
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { i as useTokenRefresh };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=useTokenRefresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTokenRefresh.js","names":[],"sources":["../../../src/auth/hooks/useTokenRefresh.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useWorkspaceToken } from \"./useWorkspaceToken\";\n\n/**\n * Automatic workspace token refresh hook\n *\n * Monitors the workspace token and automatically refreshes it\n * 5 minutes before expiry. This ensures uninterrupted access to\n * workspace resources.\n *\n * Usage:\n * ```tsx\n * // In your root App component\n * function App() {\n * useTokenRefresh({\n * workspaceAuthServiceUrl: 'http://localhost:3730/graphql',\n * refreshBeforeExpiry: 5 * 60 * 1000, // 5 minutes\n * });\n *\n * return <AppContent />;\n * }\n * ```\n */\nexport interface UseTokenRefreshOptions {\n /**\n * URL of workspace auth service GraphQL endpoint\n * Default: http://localhost:3730/graphql\n */\n workspaceAuthServiceUrl?: string;\n\n /**\n * Time before expiry to refresh token (in milliseconds)\n * Default: 5 minutes (300000ms)\n */\n refreshBeforeExpiry?: number;\n\n /**\n * Enable/disable auto-refresh\n * Default: true\n */\n enabled?: boolean;\n\n /**\n * Callback when token refresh succeeds\n */\n onRefreshSuccess?: (token: string) => void;\n\n /**\n * Callback when token refresh fails\n */\n onRefreshError?: (error: Error) => void;\n}\n\nexport function useTokenRefresh(options: UseTokenRefreshOptions = {}) {\n const {\n workspaceAuthServiceUrl = \"http://localhost:3730/graphql\",\n refreshBeforeExpiry = 5 * 60 * 1000, // 5 minutes\n enabled = true,\n onRefreshSuccess,\n onRefreshError,\n } = options;\n\n const { workspaceToken } = useAuthStore();\n const { refreshToken, getTimeUntilExpiry, isTokenExpired } =\n useWorkspaceToken({\n workspaceGatewayUrl: workspaceAuthServiceUrl,\n });\n\n const refreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n // Clear any existing timer\n if (refreshTimerRef.current) {\n clearTimeout(refreshTimerRef.current);\n refreshTimerRef.current = null;\n }\n\n // Exit if disabled or no token\n if (!enabled || !workspaceToken) {\n return;\n }\n\n // Check if token is already expired\n if (isTokenExpired(workspaceToken)) {\n console.warn(\n \"[useTokenRefresh] Token is already expired, triggering immediate refresh\",\n );\n\n refreshToken()\n .then((newToken) => {\n onRefreshSuccess?.(newToken);\n })\n .catch((error) => {\n console.error(\n \"[useTokenRefresh] Failed to refresh expired token:\",\n error,\n );\n onRefreshError?.(error);\n });\n\n return;\n }\n\n // Calculate time until refresh is needed\n const timeUntilExpiry = getTimeUntilExpiry(workspaceToken);\n const timeUntilRefresh = timeUntilExpiry - refreshBeforeExpiry;\n\n if (timeUntilRefresh <= 0) {\n // Token expires in less than refresh window, refresh immediately\n refreshToken()\n .then((newToken) => {\n onRefreshSuccess?.(newToken);\n })\n .catch((error) => {\n console.error(\n \"[useTokenRefresh] Failed to refresh token (immediate):\",\n error,\n );\n onRefreshError?.(error);\n });\n\n return;\n }\n\n // Schedule refresh\n refreshTimerRef.current = setTimeout(async () => {\n try {\n const newToken = await refreshToken();\n onRefreshSuccess?.(newToken);\n } catch (error) {\n console.error(\"[useTokenRefresh] Token refresh failed:\", error);\n onRefreshError?.(error as Error);\n\n // Optionally: Implement retry logic here\n // For now, we'll let the error propagate to the callback\n }\n }, timeUntilRefresh);\n\n // Cleanup on unmount or when dependencies change\n return () => {\n if (refreshTimerRef.current) {\n clearTimeout(refreshTimerRef.current);\n refreshTimerRef.current = null;\n }\n };\n }, [\n workspaceToken,\n enabled,\n refreshBeforeExpiry,\n refreshToken,\n getTimeUntilExpiry,\n isTokenExpired,\n onRefreshSuccess,\n onRefreshError,\n ]);\n\n // Return utility for manual refresh\n return {\n /**\n * Manually trigger a token refresh\n */\n manualRefresh: refreshToken,\n\n /**\n * Check if auto-refresh is currently scheduled\n */\n isScheduled: refreshTimerRef.current !== null,\n };\n}\n"],"mappings":";;;;AAsDA,SAAgB,EAAgB,IAAkC,EAAE,EAAE;CACpE,IAAM,EACJ,6BAA0B,iCAC1B,yBAAsB,MAAS,KAC/B,aAAU,IACV,qBACA,sBACE,GAEE,EAAE,sBAAmB,GAAc,EACnC,EAAE,iBAAc,uBAAoB,sBACxC,EAAkB,EAChB,qBAAqB,GACtB,CAAC,EAEE,IAAkB,EAA6C,KAAK;AAyF1E,QAvFA,QAAgB;AAQd,MANA,AAEE,EAAgB,aADhB,aAAa,EAAgB,QAAQ,EACX,OAIxB,CAAC,KAAW,CAAC,EACf;AAIF,MAAI,EAAe,EAAe,EAAE;AAKlC,GAJA,QAAQ,KACN,2EACD,EAED,GAAc,CACX,MAAM,MAAa;AAClB,QAAmB,EAAS;KAC5B,CACD,OAAO,MAAU;AAKhB,IAJA,QAAQ,MACN,sDACA,EACD,EACD,IAAiB,EAAM;KACvB;AAEJ;;EAKF,IAAM,IADkB,EAAmB,EAAe,GACf;AAE3C,MAAI,KAAoB,GAAG;AAEzB,MAAc,CACX,MAAM,MAAa;AAClB,QAAmB,EAAS;KAC5B,CACD,OAAO,MAAU;AAKhB,IAJA,QAAQ,MACN,0DACA,EACD,EACD,IAAiB,EAAM;KACvB;AAEJ;;AAkBF,SAdA,EAAgB,UAAU,WAAW,YAAY;AAC/C,OAAI;IACF,IAAM,IAAW,MAAM,GAAc;AACrC,QAAmB,EAAS;YACrB,GAAO;AAEd,IADA,QAAQ,MAAM,2CAA2C,EAAM,EAC/D,IAAiB,EAAe;;KAKjC,EAAiB,QAGP;AACX,GAEE,EAAgB,aADhB,aAAa,EAAgB,QAAQ,EACX;;IAG7B;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,EAGK;EAIL,eAAe;EAKf,aAAa,EAAgB,YAAY;EAC1C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { User, UserConnection, UserFilterInput, PaginationInput, DeleteUserResult } from '../types';
|
|
2
|
+
|
|
3
|
+
interface UpdateUserProfileInput {
|
|
4
|
+
username?: string;
|
|
5
|
+
firstName?: string;
|
|
6
|
+
lastName?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
phoneNumber?: string;
|
|
9
|
+
defaultWorkspaceId?: string;
|
|
10
|
+
language?: string;
|
|
11
|
+
timezone?: string;
|
|
12
|
+
}
|
|
13
|
+
interface AdminUpdateUserInput extends UpdateUserProfileInput {
|
|
14
|
+
role?: string;
|
|
15
|
+
status?: string;
|
|
16
|
+
emailVerified?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Hook for user management operations
|
|
20
|
+
*/
|
|
21
|
+
export declare function useUserOperations(): {
|
|
22
|
+
getUser: (id: string) => Promise<User | null>;
|
|
23
|
+
listUsers: (filter?: UserFilterInput, pagination?: PaginationInput) => Promise<UserConnection>;
|
|
24
|
+
updateCurrentUserProfile: (input: UpdateUserProfileInput) => Promise<User>;
|
|
25
|
+
updateUser: (id: string, input: AdminUpdateUserInput) => Promise<User>;
|
|
26
|
+
deleteUser: (id: string) => Promise<DeleteUserResult>;
|
|
27
|
+
hardDeleteUser: (id: string) => Promise<DeleteUserResult>;
|
|
28
|
+
currentUser: User | null;
|
|
29
|
+
isLoading: boolean;
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=useUserOperations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUserOperations.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/useUserOperations.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,IAAI,EACJ,cAAc,EACd,eAAe,EACf,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AA2DlB,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,oBAAqB,SAAQ,sBAAsB;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,iBAAiB;kBAqClB,MAAM,KAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;yBAiB7B,eAAe,eACX,eAAe,KAC3B,OAAO,CAAC,cAAc,CAAC;sCAwBZ,sBAAsB,KAAG,OAAO,CAAC,IAAI,CAAC;qBA8BzC,MAAM,SAAS,oBAAoB,KAAG,OAAO,CAAC,IAAI,CAAC;qBAuBnD,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAAC;yBAuBlC,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAAC;;;EAgChD"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useAuthStore as e } from "../store/authStore.js";
|
|
2
|
+
import { DeleteUserDocument as t, GetUserDocument as n, HardDeleteUserDocument as r, ListUsersDocument as i, UpdateCurrentUserProfileDocument as a, UpdateUserDocument as o } from "../../generated/global-operations.js";
|
|
3
|
+
import { useCallback as s } from "react";
|
|
4
|
+
import { useLazyQuery as c, useMutation as l } from "@apollo/client/react";
|
|
5
|
+
//#region src/auth/hooks/useUserOperations.ts
|
|
6
|
+
function u() {
|
|
7
|
+
let u = e((e) => e.user), d = e((e) => e.setUser), f = e((e) => e.setLoading), p = e((e) => e.isLoading), [m, { loading: h }] = c(n), [g, { loading: _ }] = c(i, { fetchPolicy: "network-only" }), [v] = l(a), [y] = l(o), [b] = l(t), [x] = l(r);
|
|
8
|
+
return {
|
|
9
|
+
getUser: s(async (e) => {
|
|
10
|
+
try {
|
|
11
|
+
let { data: t } = await m({ variables: { id: e } });
|
|
12
|
+
return t?.user || null;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw console.error("Failed to get user:", e), e;
|
|
15
|
+
}
|
|
16
|
+
}, [m]),
|
|
17
|
+
listUsers: s(async (e, t) => {
|
|
18
|
+
try {
|
|
19
|
+
let { data: n, error: r } = await g({ variables: {
|
|
20
|
+
filter: e,
|
|
21
|
+
pagination: t
|
|
22
|
+
} });
|
|
23
|
+
if (r) throw r;
|
|
24
|
+
return n?.users || {
|
|
25
|
+
users: [],
|
|
26
|
+
totalCount: 0,
|
|
27
|
+
hasMore: !1
|
|
28
|
+
};
|
|
29
|
+
} catch (e) {
|
|
30
|
+
if (e instanceof Error && e.name === "AbortError") return {
|
|
31
|
+
users: [],
|
|
32
|
+
totalCount: 0,
|
|
33
|
+
hasMore: !1
|
|
34
|
+
};
|
|
35
|
+
throw console.error("Failed to list users:", e), e;
|
|
36
|
+
}
|
|
37
|
+
}, [g]),
|
|
38
|
+
updateCurrentUserProfile: s(async (e) => {
|
|
39
|
+
try {
|
|
40
|
+
f(!0);
|
|
41
|
+
let { data: t } = await v({ variables: { input: e } }), n = t.updateCurrentUserProfile;
|
|
42
|
+
return u && d({
|
|
43
|
+
...u,
|
|
44
|
+
...n
|
|
45
|
+
}), n;
|
|
46
|
+
} catch (e) {
|
|
47
|
+
throw console.error("Failed to update profile:", e), e;
|
|
48
|
+
} finally {
|
|
49
|
+
f(!1);
|
|
50
|
+
}
|
|
51
|
+
}, [
|
|
52
|
+
v,
|
|
53
|
+
f,
|
|
54
|
+
d,
|
|
55
|
+
u
|
|
56
|
+
]),
|
|
57
|
+
updateUser: s(async (e, t) => {
|
|
58
|
+
try {
|
|
59
|
+
f(!0);
|
|
60
|
+
let { data: n } = await y({ variables: {
|
|
61
|
+
id: e,
|
|
62
|
+
input: t
|
|
63
|
+
} });
|
|
64
|
+
return n.updateUser;
|
|
65
|
+
} catch (e) {
|
|
66
|
+
throw console.error("Failed to update user:", e), e;
|
|
67
|
+
} finally {
|
|
68
|
+
f(!1);
|
|
69
|
+
}
|
|
70
|
+
}, [y, f]),
|
|
71
|
+
deleteUser: s(async (e) => {
|
|
72
|
+
try {
|
|
73
|
+
f(!0);
|
|
74
|
+
let { data: t } = await b({ variables: { id: e } });
|
|
75
|
+
return t.deleteUser;
|
|
76
|
+
} catch (e) {
|
|
77
|
+
throw console.error("Failed to delete user:", e), e;
|
|
78
|
+
} finally {
|
|
79
|
+
f(!1);
|
|
80
|
+
}
|
|
81
|
+
}, [b, f]),
|
|
82
|
+
hardDeleteUser: s(async (e) => {
|
|
83
|
+
try {
|
|
84
|
+
f(!0);
|
|
85
|
+
let { data: t } = await x({ variables: { id: e } });
|
|
86
|
+
return t.hardDeleteUser;
|
|
87
|
+
} catch (e) {
|
|
88
|
+
throw console.error("Failed to hard delete user:", e), e;
|
|
89
|
+
} finally {
|
|
90
|
+
f(!1);
|
|
91
|
+
}
|
|
92
|
+
}, [x, f]),
|
|
93
|
+
currentUser: u,
|
|
94
|
+
isLoading: h || _ || p
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { u as useUserOperations };
|
|
99
|
+
|
|
100
|
+
//# sourceMappingURL=useUserOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUserOperations.js","names":[],"sources":["../../../src/auth/hooks/useUserOperations.ts"],"sourcesContent":["import { useMutation, useLazyQuery } from \"@apollo/client/react\";\nimport { useCallback } from \"react\";\nimport { useAuthStore } from \"../store/authStore\";\nimport {\n GetUserDocument,\n ListUsersDocument,\n UpdateCurrentUserProfileDocument,\n UpdateUserDocument,\n DeleteUserDocument,\n HardDeleteUserDocument,\n} from \"../../generated/global-operations\";\nimport type {\n User,\n UserConnection,\n UserFilterInput,\n PaginationInput,\n DeleteUserResult,\n} from \"../types\";\n\n// =============================================================================\n// GRAPHQL RESPONSE TYPES\n// =============================================================================\n\ninterface GetUserQueryVariables {\n id: string;\n}\n\ninterface GetUserQueryResponse {\n user: User | null;\n}\n\ninterface ListUsersQueryVariables {\n filter?: UserFilterInput;\n pagination?: PaginationInput;\n}\n\ninterface ListUsersQueryResponse {\n users: UserConnection;\n}\n\ninterface UpdateCurrentUserProfileVariables {\n input: UpdateUserProfileInput;\n}\n\ninterface UpdateCurrentUserProfileResponse {\n updateCurrentUserProfile: User;\n}\n\ninterface UpdateUserVariables {\n id: string;\n input: AdminUpdateUserInput;\n}\n\ninterface UpdateUserResponse {\n updateUser: User;\n}\n\ninterface DeleteUserVariables {\n id: string;\n}\n\ninterface DeleteUserResponse {\n deleteUser: DeleteUserResult;\n}\n\ninterface HardDeleteUserVariables {\n id: string;\n}\n\ninterface HardDeleteUserResponse {\n hardDeleteUser: DeleteUserResult;\n}\n\n// GraphQL Operations\n\n// Input types for update\ninterface UpdateUserProfileInput {\n username?: string;\n firstName?: string;\n lastName?: string;\n name?: string;\n phoneNumber?: string;\n defaultWorkspaceId?: string;\n language?: string;\n timezone?: string;\n}\n\ninterface AdminUpdateUserInput extends UpdateUserProfileInput {\n role?: string;\n status?: string;\n emailVerified?: boolean;\n}\n\n/**\n * Hook for user management operations\n */\nexport function useUserOperations() {\n const user = useAuthStore((state) => state.user);\n const setUser = useAuthStore((state) => state.setUser);\n const setLoading = useAuthStore((state) => state.setLoading);\n const isLoading = useAuthStore((state) => state.isLoading);\n\n const [getUserQuery, { loading: getUserLoading }] = useLazyQuery<\n GetUserQueryResponse,\n GetUserQueryVariables\n >(GetUserDocument);\n const [listUsersQuery, { loading: listUsersLoading }] = useLazyQuery<\n ListUsersQueryResponse,\n ListUsersQueryVariables\n >(ListUsersDocument, {\n fetchPolicy: \"network-only\",\n });\n const [updateCurrentUserProfileMutation] = useMutation<\n UpdateCurrentUserProfileResponse,\n UpdateCurrentUserProfileVariables\n >(UpdateCurrentUserProfileDocument);\n const [updateUserMutation] = useMutation<\n UpdateUserResponse,\n UpdateUserVariables\n >(UpdateUserDocument);\n const [deleteUserMutation] = useMutation<\n DeleteUserResponse,\n DeleteUserVariables\n >(DeleteUserDocument);\n const [hardDeleteUserMutation] = useMutation<\n HardDeleteUserResponse,\n HardDeleteUserVariables\n >(HardDeleteUserDocument);\n\n /**\n * Get user by ID (admin only)\n */\n const getUser = useCallback(\n async (id: string): Promise<User | null> => {\n try {\n const { data } = await getUserQuery({ variables: { id } });\n return data?.user || null;\n } catch (error) {\n console.error(\"Failed to get user:\", error);\n throw error;\n }\n },\n [getUserQuery],\n );\n\n /**\n * List users with filtering and pagination (admin only)\n */\n const listUsers = useCallback(\n async (\n filter?: UserFilterInput,\n pagination?: PaginationInput,\n ): Promise<UserConnection> => {\n try {\n const { data, error } = await listUsersQuery({\n variables: { filter, pagination },\n });\n\n if (error) throw error;\n return data?.users || { users: [], totalCount: 0, hasMore: false };\n } catch (error) {\n // Ignore abort errors - they happen during component unmount/re-render\n if (error instanceof Error && error.name === \"AbortError\") {\n return { users: [], totalCount: 0, hasMore: false };\n }\n console.error(\"Failed to list users:\", error);\n throw error;\n }\n },\n [listUsersQuery],\n );\n\n /**\n * Update current user's profile\n */\n const updateCurrentUserProfile = useCallback(\n async (input: UpdateUserProfileInput): Promise<User> => {\n try {\n setLoading(true);\n\n const { data } = await updateCurrentUserProfileMutation({\n variables: { input },\n });\n\n const updatedUser = data!.updateCurrentUserProfile;\n\n // Update user in store\n if (user) {\n setUser({ ...user, ...updatedUser });\n }\n\n return updatedUser;\n } catch (error) {\n console.error(\"Failed to update profile:\", error);\n throw error;\n } finally {\n setLoading(false);\n }\n },\n [updateCurrentUserProfileMutation, setLoading, setUser, user],\n );\n\n /**\n * Update user by ID (admin only)\n */\n const updateUser = useCallback(\n async (id: string, input: AdminUpdateUserInput): Promise<User> => {\n try {\n setLoading(true);\n\n const { data } = await updateUserMutation({\n variables: { id, input },\n });\n\n return data!.updateUser;\n } catch (error) {\n console.error(\"Failed to update user:\", error);\n throw error;\n } finally {\n setLoading(false);\n }\n },\n [updateUserMutation, setLoading],\n );\n\n /**\n * Delete user (soft delete, admin only)\n */\n const deleteUser = useCallback(\n async (id: string): Promise<DeleteUserResult> => {\n try {\n setLoading(true);\n\n const { data } = await deleteUserMutation({\n variables: { id },\n });\n\n return data!.deleteUser;\n } catch (error) {\n console.error(\"Failed to delete user:\", error);\n throw error;\n } finally {\n setLoading(false);\n }\n },\n [deleteUserMutation, setLoading],\n );\n\n /**\n * Hard delete user (permanent, super admin only)\n */\n const hardDeleteUser = useCallback(\n async (id: string): Promise<DeleteUserResult> => {\n try {\n setLoading(true);\n\n const { data } = await hardDeleteUserMutation({\n variables: { id },\n });\n\n return data!.hardDeleteUser;\n } catch (error) {\n console.error(\"Failed to hard delete user:\", error);\n throw error;\n } finally {\n setLoading(false);\n }\n },\n [hardDeleteUserMutation, setLoading],\n );\n\n return {\n // Queries\n getUser,\n listUsers,\n // Mutations\n updateCurrentUserProfile,\n updateUser,\n deleteUser,\n hardDeleteUser,\n // State\n currentUser: user,\n isLoading: getUserLoading || listUsersLoading || isLoading,\n };\n}\n"],"mappings":";;;;;AAgGA,SAAgB,IAAoB;CAClC,IAAM,IAAO,GAAc,MAAU,EAAM,KAAK,EAC1C,IAAU,GAAc,MAAU,EAAM,QAAQ,EAChD,IAAa,GAAc,MAAU,EAAM,WAAW,EACtD,IAAY,GAAc,MAAU,EAAM,UAAU,EAEpD,CAAC,GAAc,EAAE,SAAS,OAAoB,EAGlD,EAAgB,EACZ,CAAC,GAAgB,EAAE,SAAS,OAAsB,EAGtD,GAAmB,EACnB,aAAa,gBACd,CAAC,EACI,CAAC,KAAoC,EAGzC,EAAiC,EAC7B,CAAC,KAAsB,EAG3B,EAAmB,EACf,CAAC,KAAsB,EAG3B,EAAmB,EACf,CAAC,KAA0B,EAG/B,EAAuB;AAgJzB,QAAO;EAEL,SA7Ic,EACd,OAAO,MAAqC;AAC1C,OAAI;IACF,IAAM,EAAE,YAAS,MAAM,EAAa,EAAE,WAAW,EAAE,OAAI,EAAE,CAAC;AAC1D,WAAO,GAAM,QAAQ;YACd,GAAO;AAEd,UADA,QAAQ,MAAM,uBAAuB,EAAM,EACrC;;KAGV,CAAC,EAAa,CACf;EAmIC,WA9HgB,EAChB,OACE,GACA,MAC4B;AAC5B,OAAI;IACF,IAAM,EAAE,SAAM,aAAU,MAAM,EAAe,EAC3C,WAAW;KAAE;KAAQ;KAAY,EAClC,CAAC;AAEF,QAAI,EAAO,OAAM;AACjB,WAAO,GAAM,SAAS;KAAE,OAAO,EAAE;KAAE,YAAY;KAAG,SAAS;KAAO;YAC3D,GAAO;AAEd,QAAI,aAAiB,SAAS,EAAM,SAAS,aAC3C,QAAO;KAAE,OAAO,EAAE;KAAE,YAAY;KAAG,SAAS;KAAO;AAGrD,UADA,QAAQ,MAAM,yBAAyB,EAAM,EACvC;;KAGV,CAAC,EAAe,CACjB;EA0GC,0BArG+B,EAC/B,OAAO,MAAiD;AACtD,OAAI;AACF,MAAW,GAAK;IAEhB,IAAM,EAAE,YAAS,MAAM,EAAiC,EACtD,WAAW,EAAE,UAAO,EACrB,CAAC,EAEI,IAAc,EAAM;AAO1B,WAJI,KACF,EAAQ;KAAE,GAAG;KAAM,GAAG;KAAa,CAAC,EAG/B;YACA,GAAO;AAEd,UADA,QAAQ,MAAM,6BAA6B,EAAM,EAC3C;aACE;AACR,MAAW,GAAM;;KAGrB;GAAC;GAAkC;GAAY;GAAS;GAAK,CAC9D;EA6EC,YAxEiB,EACjB,OAAO,GAAY,MAA+C;AAChE,OAAI;AACF,MAAW,GAAK;IAEhB,IAAM,EAAE,YAAS,MAAM,EAAmB,EACxC,WAAW;KAAE;KAAI;KAAO,EACzB,CAAC;AAEF,WAAO,EAAM;YACN,GAAO;AAEd,UADA,QAAQ,MAAM,0BAA0B,EAAM,EACxC;aACE;AACR,MAAW,GAAM;;KAGrB,CAAC,GAAoB,EAAW,CACjC;EAuDC,YAlDiB,EACjB,OAAO,MAA0C;AAC/C,OAAI;AACF,MAAW,GAAK;IAEhB,IAAM,EAAE,YAAS,MAAM,EAAmB,EACxC,WAAW,EAAE,OAAI,EAClB,CAAC;AAEF,WAAO,EAAM;YACN,GAAO;AAEd,UADA,QAAQ,MAAM,0BAA0B,EAAM,EACxC;aACE;AACR,MAAW,GAAM;;KAGrB,CAAC,GAAoB,EAAW,CACjC;EAiCC,gBA5BqB,EACrB,OAAO,MAA0C;AAC/C,OAAI;AACF,MAAW,GAAK;IAEhB,IAAM,EAAE,YAAS,MAAM,EAAuB,EAC5C,WAAW,EAAE,OAAI,EAClB,CAAC;AAEF,WAAO,EAAM;YACN,GAAO;AAEd,UADA,QAAQ,MAAM,+BAA+B,EAAM,EAC7C;aACE;AACR,MAAW,GAAM;;KAGrB,CAAC,GAAwB,EAAW,CACrC;EAYC,aAAa;EACb,WAAW,KAAkB,KAAoB;EAClD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useMutation } from '@apollo/client/react';
|
|
2
|
+
import { WorkspaceTokenResponse, SecretRotationResponse, RotateWorkspaceSecretInput } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook for workspace token and secret operations
|
|
6
|
+
*/
|
|
7
|
+
export declare function useWorkspaceOperations(): {
|
|
8
|
+
generateWorkspaceToken: (_workspaceId: string) => Promise<WorkspaceTokenResponse>;
|
|
9
|
+
switchWorkspace: (workspaceId: string) => Promise<WorkspaceTokenResponse>;
|
|
10
|
+
createWorkspaceSecret: (_workspaceId: string) => Promise<boolean>;
|
|
11
|
+
rotateWorkspaceSecret: (_input: RotateWorkspaceSecretInput) => Promise<SecretRotationResponse>;
|
|
12
|
+
revokeWorkspaceSecret: (_workspaceId: string) => Promise<boolean>;
|
|
13
|
+
revokeWorkspaceToken: (_token: string, _reason?: string) => Promise<boolean>;
|
|
14
|
+
revokeAllMyWorkspaceTokens: (_reason?: string) => Promise<number>;
|
|
15
|
+
clearWorkspace: () => void;
|
|
16
|
+
createWorkspaceMutation: useMutation.MutationFunction<unknown, {
|
|
17
|
+
[x: string]: any;
|
|
18
|
+
}, import('@apollo/client').ApolloCache>;
|
|
19
|
+
updateWorkspaceMutation: useMutation.MutationFunction<unknown, {
|
|
20
|
+
[x: string]: any;
|
|
21
|
+
}, import('@apollo/client').ApolloCache>;
|
|
22
|
+
addWorkspaceMemberMutation: useMutation.MutationFunction<unknown, {
|
|
23
|
+
[x: string]: any;
|
|
24
|
+
}, import('@apollo/client').ApolloCache>;
|
|
25
|
+
updateWorkspaceMemberMutation: useMutation.MutationFunction<unknown, {
|
|
26
|
+
[x: string]: any;
|
|
27
|
+
}, import('@apollo/client').ApolloCache>;
|
|
28
|
+
removeWorkspaceMemberMutation: useMutation.MutationFunction<unknown, {
|
|
29
|
+
[x: string]: any;
|
|
30
|
+
}, import('@apollo/client').ApolloCache>;
|
|
31
|
+
currentWorkspaceId: string | null;
|
|
32
|
+
workspaceToken: string | null;
|
|
33
|
+
isLoading: boolean;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=useWorkspaceOperations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspaceOperations.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/useWorkspaceOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AASnD,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC3B,MAAM,UAAU,CAAC;AAalB;;GAEG;AACH,wBAAgB,sBAAsB;2CAqBpB,MAAM,KACnB,OAAO,CAAC,sBAAsB,CAAC;mCAcnB,MAAM,KAClB,OAAO,CAAC,sBAAsB,CAAC;0CAalB,MAAM,KACnB,OAAO,CAAC,OAAO,CAAC;oCAYT,0BAA0B,KACjC,OAAO,CAAC,sBAAsB,CAAC;0CAclB,MAAM,KACnB,OAAO,CAAC,OAAO,CAAC;mCAYT,MAAM,YACJ,MAAM,KACf,OAAO,CAAC,OAAO,CAAC;2CAYP,MAAM,KACf,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;EAmCnB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useAuthStore as e } from "../store/authStore.js";
|
|
2
|
+
import { AddWorkspaceMemberDocument as t, CreateWorkspaceDocument as n, RemoveWorkspaceMemberDocument as r, UpdateWorkspaceDocument as i, UpdateWorkspaceMemberDocument as a } from "../../generated/global-operations.js";
|
|
3
|
+
import { useMutation as o } from "@apollo/client/react";
|
|
4
|
+
//#region src/auth/hooks/useWorkspaceOperations.ts
|
|
5
|
+
function s() {
|
|
6
|
+
let s = e(), [c] = o(n), [l] = o(i), [u] = o(t), [d] = o(a), [f] = o(r), p = async (e) => {
|
|
7
|
+
throw console.warn("generateWorkspaceToken: Use useMyWorkspaces().issueWorkspaceToken() instead. This operation requires the workspace gateway."), Error("Use useMyWorkspaces().issueWorkspaceToken() for workspace token issuance");
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
generateWorkspaceToken: p,
|
|
11
|
+
switchWorkspace: async (e) => (s.clearWorkspace(), p(e)),
|
|
12
|
+
createWorkspaceSecret: async (e) => (console.warn("createWorkspaceSecret is not available from the global auth client"), !1),
|
|
13
|
+
rotateWorkspaceSecret: async (e) => {
|
|
14
|
+
throw console.warn("rotateWorkspaceSecret is not available from the global auth client"), Error("rotateWorkspaceSecret is not available from the global auth client");
|
|
15
|
+
},
|
|
16
|
+
revokeWorkspaceSecret: async (e) => (console.warn("revokeWorkspaceSecret is not available from the global auth client"), !1),
|
|
17
|
+
revokeWorkspaceToken: async (e, t) => (console.warn("revokeWorkspaceToken is not available from the global auth client"), !1),
|
|
18
|
+
revokeAllMyWorkspaceTokens: async (e) => (console.warn("revokeAllMyWorkspaceTokens is not available from the global auth client"), 0),
|
|
19
|
+
clearWorkspace: () => {
|
|
20
|
+
s.clearWorkspace();
|
|
21
|
+
},
|
|
22
|
+
createWorkspaceMutation: c,
|
|
23
|
+
updateWorkspaceMutation: l,
|
|
24
|
+
addWorkspaceMemberMutation: u,
|
|
25
|
+
updateWorkspaceMemberMutation: d,
|
|
26
|
+
removeWorkspaceMemberMutation: f,
|
|
27
|
+
currentWorkspaceId: s.currentWorkspaceId,
|
|
28
|
+
workspaceToken: s.workspaceToken,
|
|
29
|
+
isLoading: s.isLoading
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { s as useWorkspaceOperations };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=useWorkspaceOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspaceOperations.js","names":[],"sources":["../../../src/auth/hooks/useWorkspaceOperations.ts"],"sourcesContent":["import { useMutation } from \"@apollo/client/react\";\nimport { useAuthStore } from \"../store/authStore\";\nimport {\n CreateWorkspaceDocument,\n UpdateWorkspaceDocument,\n AddWorkspaceMemberDocument,\n UpdateWorkspaceMemberDocument,\n RemoveWorkspaceMemberDocument,\n} from \"../../generated/global-operations\";\nimport type {\n WorkspaceTokenResponse,\n SecretRotationResponse,\n RotateWorkspaceSecretInput,\n} from \"../types\";\n\n// =============================================================================\n// NOTE: Workspace token/secret operations (issueWorkspaceToken,\n// createWorkspaceSecret, rotateWorkspaceSecret, revokeWorkspaceSecret,\n// revokeWorkspaceToken, revokeAllMyWorkspaceTokens) are in the wspace-auth-svc\n// schema (workspace gateway), NOT the global gateway. These operations are\n// handled by useMyWorkspaces.ts (via graphqlFetch to workspace gateway).\n//\n// The workspace CRUD operations (createWorkspace, updateWorkspace, etc.) are\n// in the global gateway schema and use generated Document constants.\n// =============================================================================\n\n/**\n * Hook for workspace token and secret operations\n */\nexport function useWorkspaceOperations() {\n const store = useAuthStore();\n\n // Workspace CRUD mutations (available in global gateway schema)\n const [createWorkspaceMutation] = useMutation(CreateWorkspaceDocument);\n const [updateWorkspaceMutation] = useMutation(UpdateWorkspaceDocument);\n const [addWorkspaceMemberMutation] = useMutation(AddWorkspaceMemberDocument);\n const [updateWorkspaceMemberMutation] = useMutation(\n UpdateWorkspaceMemberDocument,\n );\n const [removeWorkspaceMemberMutation] = useMutation(\n RemoveWorkspaceMemberDocument,\n );\n\n /**\n * Generate workspace token for a workspace.\n * This hook intentionally delegates workspace-token issuance to\n * `useMyWorkspaces().issueWorkspaceToken()` because that flow requires the\n * workspaces gateway rather than the global Apollo client.\n */\n const generateWorkspaceToken = async (\n _workspaceId: string,\n ): Promise<WorkspaceTokenResponse> => {\n console.warn(\n \"generateWorkspaceToken: Use useMyWorkspaces().issueWorkspaceToken() instead. \" +\n \"This operation requires the workspace gateway.\",\n );\n throw new Error(\n \"Use useMyWorkspaces().issueWorkspaceToken() for workspace token issuance\",\n );\n };\n\n /**\n * Switch to a different workspace\n */\n const switchWorkspace = async (\n workspaceId: string,\n ): Promise<WorkspaceTokenResponse> => {\n // Clear current workspace token first\n store.clearWorkspace();\n\n // Generate new workspace token\n return generateWorkspaceToken(workspaceId);\n };\n\n /**\n * Create workspace secret (admin only).\n * Unsupported from this hook because the operation lives on the workspaces gateway.\n */\n const createWorkspaceSecret = async (\n _workspaceId: string,\n ): Promise<boolean> => {\n console.warn(\n \"createWorkspaceSecret is not available from the global auth client\",\n );\n return false;\n };\n\n /**\n * Rotate workspace secret (admin only).\n * Unsupported from this hook because the operation lives on the workspaces gateway.\n */\n const rotateWorkspaceSecret = async (\n _input: RotateWorkspaceSecretInput,\n ): Promise<SecretRotationResponse> => {\n console.warn(\n \"rotateWorkspaceSecret is not available from the global auth client\",\n );\n throw new Error(\n \"rotateWorkspaceSecret is not available from the global auth client\",\n );\n };\n\n /**\n * Revoke workspace secret (emergency use, admin only).\n * Unsupported from this hook because the operation lives on the workspaces gateway.\n */\n const revokeWorkspaceSecret = async (\n _workspaceId: string,\n ): Promise<boolean> => {\n console.warn(\n \"revokeWorkspaceSecret is not available from the global auth client\",\n );\n return false;\n };\n\n /**\n * Revoke a specific workspace token.\n * Unsupported from this hook because the operation lives on the workspaces gateway.\n */\n const revokeWorkspaceToken = async (\n _token: string,\n _reason?: string,\n ): Promise<boolean> => {\n console.warn(\n \"revokeWorkspaceToken is not available from the global auth client\",\n );\n return false;\n };\n\n /**\n * Revoke all workspace tokens for current user.\n * Unsupported from this hook because the operation lives on the workspaces gateway.\n */\n const revokeAllMyWorkspaceTokens = async (\n _reason?: string,\n ): Promise<number> => {\n console.warn(\n \"revokeAllMyWorkspaceTokens is not available from the global auth client\",\n );\n return 0;\n };\n\n /**\n * Clear current workspace (logout from workspace)\n */\n const clearWorkspace = () => {\n store.clearWorkspace();\n };\n\n return {\n // Mutations\n generateWorkspaceToken,\n switchWorkspace,\n createWorkspaceSecret,\n rotateWorkspaceSecret,\n revokeWorkspaceSecret,\n revokeWorkspaceToken,\n revokeAllMyWorkspaceTokens,\n clearWorkspace,\n // Workspace CRUD mutations\n createWorkspaceMutation,\n updateWorkspaceMutation,\n addWorkspaceMemberMutation,\n updateWorkspaceMemberMutation,\n removeWorkspaceMemberMutation,\n // State\n currentWorkspaceId: store.currentWorkspaceId,\n workspaceToken: store.workspaceToken,\n isLoading: store.isLoading,\n };\n}\n"],"mappings":";;;;AA6BA,SAAgB,IAAyB;CACvC,IAAM,IAAQ,GAAc,EAGtB,CAAC,KAA2B,EAAY,EAAwB,EAChE,CAAC,KAA2B,EAAY,EAAwB,EAChE,CAAC,KAA8B,EAAY,EAA2B,EACtE,CAAC,KAAiC,EACtC,EACD,EACK,CAAC,KAAiC,EACtC,EACD,EAQK,IAAyB,OAC7B,MACoC;AAKpC,QAJA,QAAQ,KACN,8HAED,EACS,MACR,2EACD;;AA2FH,QAAO;EAEL;EACA,iBAxFsB,OACtB,OAGA,EAAM,gBAAgB,EAGf,EAAuB,EAAY;EAkF1C,uBA3E4B,OAC5B,OAEA,QAAQ,KACN,qEACD,EACM;EAsEP,uBA/D4B,OAC5B,MACoC;AAIpC,SAHA,QAAQ,KACN,qEACD,EACS,MACR,qEACD;;EAwDD,uBAjD4B,OAC5B,OAEA,QAAQ,KACN,qEACD,EACM;EA4CP,sBArC2B,OAC3B,GACA,OAEA,QAAQ,KACN,oEACD,EACM;EA+BP,4BAxBiC,OACjC,OAEA,QAAQ,KACN,0EACD,EACM;EAmBP,sBAb2B;AAC3B,KAAM,gBAAgB;;EActB;EACA;EACA;EACA;EACA;EAEA,oBAAoB,EAAM;EAC1B,gBAAgB,EAAM;EACtB,WAAW,EAAM;EAClB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace token management hook
|
|
3
|
+
*
|
|
4
|
+
* Provides functions to issue, refresh, and verify workspace tokens.
|
|
5
|
+
* Automatically updates the auth store with new tokens.
|
|
6
|
+
*
|
|
7
|
+
* API Flow:
|
|
8
|
+
* - Calls workspace gateway (https://gw-wspace.local.burdenoff.com/workspaces/graphql)
|
|
9
|
+
* - Gateway federates wspace-auth-svc which handles token operations
|
|
10
|
+
* - Auth token (from global-auth-svc) goes in Authorization header
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const { issueToken, refreshToken, verifyToken, isLoading, error } = useWorkspaceToken({
|
|
15
|
+
* workspaceGatewayUrl: 'https://gw-wspace.local.burdenoff.com/workspaces/graphql'
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // After login and organization/workspace selection
|
|
19
|
+
* await issueToken(organizationId, workspaceId);
|
|
20
|
+
*
|
|
21
|
+
* // Refresh token before expiry (uses stored org/workspace IDs)
|
|
22
|
+
* await refreshToken();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export interface UseWorkspaceTokenOptions {
|
|
26
|
+
/**
|
|
27
|
+
* URL of workspace gateway GraphQL endpoint
|
|
28
|
+
* Default: https://gw-wspace.local.burdenoff.com/workspaces/graphql
|
|
29
|
+
*
|
|
30
|
+
* Note: This should point to the workspace gateway, NOT directly to wspace-auth-svc.
|
|
31
|
+
* The gateway federates wspace-auth-svc and handles routing.
|
|
32
|
+
*/
|
|
33
|
+
workspaceGatewayUrl?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface WorkspaceTokenPayload {
|
|
36
|
+
sub: string;
|
|
37
|
+
workspaceId: string;
|
|
38
|
+
tenantId?: string;
|
|
39
|
+
email?: string;
|
|
40
|
+
username?: string;
|
|
41
|
+
role?: string;
|
|
42
|
+
scopes: string[];
|
|
43
|
+
iat: number;
|
|
44
|
+
exp: number;
|
|
45
|
+
}
|
|
46
|
+
export declare function useWorkspaceToken(options?: UseWorkspaceTokenOptions): {
|
|
47
|
+
issueToken: (organizationId: string, workspaceId?: string, projectId?: string, scopes?: string[]) => Promise<string>;
|
|
48
|
+
refreshToken: () => Promise<string>;
|
|
49
|
+
verifyToken: (token?: string) => Promise<WorkspaceTokenPayload>;
|
|
50
|
+
decodeToken: (token: string) => WorkspaceTokenPayload;
|
|
51
|
+
isTokenExpired: (token?: string) => boolean;
|
|
52
|
+
getTimeUntilExpiry: (token?: string) => number;
|
|
53
|
+
isLoading: boolean;
|
|
54
|
+
error: string | null;
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=useWorkspaceToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspaceToken.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/useWorkspaceToken.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B;iCAkBlD,MAAM,gBACR,MAAM,cACR,MAAM,WACT,MAAM,EAAE,KAChB,OAAO,CAAC,MAAM,CAAC;wBAoKuB,OAAO,CAAC,MAAM,CAAC;0BA7EzC,MAAM,KAAG,OAAO,CAAC,qBAAqB,CAAC;yBAyFhB,MAAM,KAAG,qBAAqB;6BAoB3D,MAAM,KAAG,OAAO;iCAsBhB,MAAM,KAAG,MAAM;;;EA6B3B"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useAuthStore as e } from "../store/authStore.js";
|
|
2
|
+
import { useCallback as t, useState as n } from "react";
|
|
3
|
+
import { graphqlFetch as r } from "@burdenoff/fe-libs/shared/graphql/fetch";
|
|
4
|
+
//#region src/auth/hooks/useWorkspaceToken.ts
|
|
5
|
+
function i(i = {}) {
|
|
6
|
+
let { workspaceGatewayUrl: a = "https://gw-wspace.local.burdenoff.com/workspaces/graphql" } = i, [o, s] = n(!1), [c, l] = n(null), u = t(async (t, n, i, a) => {
|
|
7
|
+
s(!0), l(null);
|
|
8
|
+
try {
|
|
9
|
+
let o = e.getState().accessToken;
|
|
10
|
+
if (!o) throw Error("No access token available. Please login first.");
|
|
11
|
+
let c = (await r({
|
|
12
|
+
gateway: "workspace",
|
|
13
|
+
query: "\n mutation IssueWorkspaceToken($input: IssueWorkspaceTokenInput!) {\n issueWorkspaceToken(input: $input) {\n success\n token\n expiresAt\n organizationId\n workspaceId\n projectId\n scopes\n error {\n code\n message\n }\n }\n }\n ",
|
|
14
|
+
variables: { input: {
|
|
15
|
+
organizationId: t,
|
|
16
|
+
...n && { workspaceId: n },
|
|
17
|
+
...i && { projectId: i },
|
|
18
|
+
...a && { scopes: a }
|
|
19
|
+
} },
|
|
20
|
+
authToken: o
|
|
21
|
+
})).data?.issueWorkspaceToken;
|
|
22
|
+
if (!c?.success || !c?.token) {
|
|
23
|
+
let e = typeof c?.error?.message == "string" ? c.error.message : typeof c?.error == "string" ? c.error : "Failed to issue workspace token";
|
|
24
|
+
throw Error(e);
|
|
25
|
+
}
|
|
26
|
+
return e.getState().setWorkspaceToken(c.token), e.getState().setCurrentWorkspaceId(c.workspaceId), s(!1), c.token;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
let t = e instanceof Error ? e.message : "Unknown error occurred";
|
|
29
|
+
throw console.error("[useWorkspaceToken] Error issuing token:", t), l(t), s(!1), e;
|
|
30
|
+
}
|
|
31
|
+
}, [a]), d = t(async (t) => {
|
|
32
|
+
s(!0), l(null);
|
|
33
|
+
try {
|
|
34
|
+
let { workspaceToken: n } = e.getState(), i = t || n;
|
|
35
|
+
if (!i) throw Error("No workspace token available to verify");
|
|
36
|
+
let a = (await r({
|
|
37
|
+
gateway: "workspace",
|
|
38
|
+
query: "\n query VerifyWorkspaceToken($token: String!) {\n verifyWorkspaceToken(token: $token) {\n valid\n payload {\n sub\n workspaceId\n tenantId\n email\n username\n role\n scopes\n iat\n exp\n }\n error {\n code\n message\n }\n }\n }\n ",
|
|
39
|
+
variables: { token: i }
|
|
40
|
+
})).data?.verifyWorkspaceToken;
|
|
41
|
+
if (!a?.valid) {
|
|
42
|
+
let e = typeof a?.error?.message == "string" ? a.error.message : typeof a?.error == "string" ? a.error : "Token verification failed";
|
|
43
|
+
throw Error(e);
|
|
44
|
+
}
|
|
45
|
+
return s(!1), a.payload;
|
|
46
|
+
} catch (e) {
|
|
47
|
+
let t = e instanceof Error ? e.message : "Unknown error occurred";
|
|
48
|
+
throw console.error("[useWorkspaceToken] Error verifying token:", t), l(t), s(!1), e;
|
|
49
|
+
}
|
|
50
|
+
}, [a]), f = t(async () => {
|
|
51
|
+
let { currentOrganizationId: t, currentWorkspaceId: n } = e.getState();
|
|
52
|
+
if (!t) throw Error("No organization ID in store. Please login first.");
|
|
53
|
+
return u(t, n ?? void 0);
|
|
54
|
+
}, [u]), p = t((e) => {
|
|
55
|
+
try {
|
|
56
|
+
let t = e.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), n = decodeURIComponent(atob(t).split("").map((e) => "%" + ("00" + e.charCodeAt(0).toString(16)).slice(-2)).join(""));
|
|
57
|
+
return JSON.parse(n);
|
|
58
|
+
} catch {
|
|
59
|
+
throw Error("Failed to decode token");
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
return {
|
|
63
|
+
issueToken: u,
|
|
64
|
+
refreshToken: f,
|
|
65
|
+
verifyToken: d,
|
|
66
|
+
decodeToken: p,
|
|
67
|
+
isTokenExpired: t((t) => {
|
|
68
|
+
try {
|
|
69
|
+
let { workspaceToken: n } = e.getState(), r = t || n;
|
|
70
|
+
if (!r) return !0;
|
|
71
|
+
let i = p(r), a = Math.floor(Date.now() / 1e3);
|
|
72
|
+
return i.exp < a;
|
|
73
|
+
} catch {
|
|
74
|
+
return !0;
|
|
75
|
+
}
|
|
76
|
+
}, [p]),
|
|
77
|
+
getTimeUntilExpiry: t((t) => {
|
|
78
|
+
try {
|
|
79
|
+
let { workspaceToken: n } = e.getState(), r = t || n;
|
|
80
|
+
if (!r) return 0;
|
|
81
|
+
let i = p(r), a = Math.floor(Date.now() / 1e3), o = (i.exp - a) * 1e3;
|
|
82
|
+
return Math.max(0, o);
|
|
83
|
+
} catch {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
}, [p]),
|
|
87
|
+
isLoading: o,
|
|
88
|
+
error: c
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { i as useWorkspaceToken };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=useWorkspaceToken.js.map
|