@memberjunction/ng-explorer-core 6.2.0-edge.0 → 6.2.0-edge.2
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/app-routing.module.d.ts +23 -1
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +50 -14
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +12 -1
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/command-palette/command-palette.component.d.ts +7 -1
- package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
- package/dist/lib/command-palette/command-palette.component.js +28 -14
- package/dist/lib/command-palette/command-palette.component.js.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.d.ts +103 -13
- package/dist/lib/conversation-feedback/conversation-feedback.d.ts.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.js +219 -67
- package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts +64 -10
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +172 -66
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/generic/resource-container-component.d.ts +19 -5
- package/dist/lib/generic/resource-container-component.d.ts.map +1 -1
- package/dist/lib/generic/resource-container-component.js +43 -13
- package/dist/lib/generic/resource-container-component.js.map +1 -1
- package/dist/lib/guards/entities.guard.d.ts +4 -0
- package/dist/lib/guards/entities.guard.d.ts.map +1 -1
- package/dist/lib/guards/entities.guard.js +10 -2
- package/dist/lib/guards/entities.guard.js.map +1 -1
- package/dist/lib/identity-claims/claim-redeem.component.d.ts +4 -0
- package/dist/lib/identity-claims/claim-redeem.component.d.ts.map +1 -1
- package/dist/lib/identity-claims/claim-redeem.component.js +10 -2
- package/dist/lib/identity-claims/claim-redeem.component.js.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts +4 -0
- package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +10 -2
- package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
- package/dist/lib/profile/profile-dialog.component.d.ts.map +1 -1
- package/dist/lib/profile/profile-dialog.component.js +194 -191
- package/dist/lib/profile/profile-dialog.component.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +20 -2
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +33 -9
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +80 -10
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +168 -56
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +199 -25
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +534 -182
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts +2 -0
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.js +5 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-search-routing.d.ts +25 -0
- package/dist/lib/resource-wrappers/chat-search-routing.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-search-routing.js +24 -0
- package/dist/lib/resource-wrappers/chat-search-routing.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +14 -2
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +32 -8
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts +46 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js +62 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js.map +1 -0
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +54 -8
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +138 -46
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts +223 -30
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js +438 -118
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +7 -3
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +23 -15
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +74 -11
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +214 -68
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/server-connectivity.service.d.ts +9 -4
- package/dist/lib/services/server-connectivity.service.d.ts.map +1 -1
- package/dist/lib/services/server-connectivity.service.js +56 -12
- package/dist/lib/services/server-connectivity.service.js.map +1 -1
- package/dist/lib/services/startup-validation.service.d.ts +4 -0
- package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
- package/dist/lib/services/startup-validation.service.js +10 -2
- package/dist/lib/services/startup-validation.service.js.map +1 -1
- package/dist/lib/services/system-validation.service.d.ts +13 -1
- package/dist/lib/services/system-validation.service.d.ts.map +1 -1
- package/dist/lib/services/system-validation.service.js +29 -5
- package/dist/lib/services/system-validation.service.js.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts +54 -4
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +130 -40
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts +29 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.js +56 -12
- package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.d.ts +33 -5
- package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.js +85 -29
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +50 -6
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js +95 -22
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +91 -9
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +257 -101
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/loading-themes.d.ts +16 -12
- package/dist/lib/shell/loading-themes.d.ts.map +1 -1
- package/dist/lib/shell/loading-themes.js +145 -137
- package/dist/lib/shell/loading-themes.js.map +1 -1
- package/dist/lib/shell/readiness-beacon.d.ts +2 -0
- package/dist/lib/shell/readiness-beacon.d.ts.map +1 -1
- package/dist/lib/shell/readiness-beacon.js +5 -1
- package/dist/lib/shell/readiness-beacon.js.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/about-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.js +16 -4
- package/dist/lib/shell/services/about-dialog.service.js.map +1 -1
- package/dist/lib/shell/services/profile-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/profile-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/profile-dialog.service.js +16 -4
- package/dist/lib/shell/services/profile-dialog.service.js.map +1 -1
- package/dist/lib/shell/services/user-sharing-center-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/user-sharing-center-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/user-sharing-center-dialog.service.js +15 -3
- package/dist/lib/shell/services/user-sharing-center-dialog.service.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +264 -39
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +697 -294
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +64 -8
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +129 -37
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts +26 -2
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +48 -10
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +84 -6
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +133 -29
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts +173 -23
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +383 -109
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +383 -55
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +962 -326
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-query/single-query.component.d.ts +22 -2
- package/dist/lib/single-query/single-query.component.d.ts.map +1 -1
- package/dist/lib/single-query/single-query.component.js +40 -10
- package/dist/lib/single-query/single-query.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +41 -3
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +71 -11
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts +23 -3
- package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +42 -12
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/system-validation/system-validation-banner.component.d.ts +12 -2
- package/dist/lib/system-validation/system-validation-banner.component.d.ts.map +1 -1
- package/dist/lib/system-validation/system-validation-banner.component.js +25 -5
- package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
- package/dist/lib/user-menu/user-menu.types.d.ts +4 -0
- package/dist/lib/user-menu/user-menu.types.d.ts.map +1 -1
- package/dist/lib/user-menu/user-menu.types.js +10 -2
- package/dist/lib/user-menu/user-menu.types.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +59 -7
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +151 -47
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.d.ts +3 -2
- package/dist/lib/user-profile/user-profile.component.d.ts.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +5 -4
- package/dist/lib/user-profile/user-profile.component.js.map +1 -1
- package/package.json +52 -52
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claim-redeem.component.js","sourceRoot":"","sources":["../../../src/lib/identity-claims/claim-redeem.component.ts","../../../src/lib/identity-claims/claim-redeem.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Identity Claim Redemption Page\n *\n * Landing page for the links in identity-claim emails\n * (`${PORTAL_BASE_URL}/claims/redeem?id=<claimId>&token=<rawToken>`). When a recipient\n * clicks through, this component:\n * 1. Waits for the user's session to be restored (same posture as the OAuth callback —\n * no AuthGuard; the component handles the not-yet-authenticated case itself)\n * 2. Extracts the claim id and optional verification token from the query params\n * 3. Calls the `RedeemIdentityClaim` GraphQL mutation, which runs the server engine's full\n * gate (email match subject to verification rules, or timing-safe token match, atomic CAS)\n * 4. Shows the outcome and offers navigation back into the app\n *\n * Like the OAuth callback, this is a deliberate exception to the NavigationService-only rule:\n * it is registered directly in the routing module and reads its own query params.\n *\n * @module IdentityClaims\n */\n\nimport { Component, OnDestroy, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\ninterface RedeemIdentityClaimResponse {\n RedeemIdentityClaim?: {\n Success: boolean;\n ErrorMessage?: string;\n ClaimID?: string;\n Data?: string;\n };\n}\n\n/** Maximum time to wait for session restoration (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\nconst REDEEM_MUTATION = `\n mutation RedeemIdentityClaim($ClaimID: String!, $Token: String) {\n RedeemIdentityClaim(ClaimID: $ClaimID, Token: $Token) {\n Success\n ErrorMessage\n ClaimID\n Data\n }\n }\n`;\n\n@Component({\n standalone: false,\n selector: 'mj-claim-redeem',\n templateUrl: './claim-redeem.component.html',\n styleUrls: ['./claim-redeem.component.css']\n})\nexport class ClaimRedeemComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /** Loading state while restoring the session / redeeming */\n public IsLoading = true;\n\n /** Terminal error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** True when the wait for authentication timed out (user likely not signed in) */\n public NeedsSignIn = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n await this.waitForProviderAndRedeem();\n }\n\n ngOnDestroy(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete),\n * then redeems the claim from the query params.\n */\n private async waitForProviderAndRedeem(): Promise<void> {\n const startTime = Date.now();\n\n if (this.isProviderReady()) {\n await this.safeRedeem();\n return;\n }\n\n this.StatusMessage = 'Waiting for sign-in...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeRedeem();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.NeedsSignIn = true;\n this.showError('Please sign in first, then open the link from your email again — the claim will attach to your signed-in account.');\n resolve();\n return;\n }\n\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for sign-in... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /** Checks if the GraphQL provider is initialized with a valid token */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n return Boolean(configData && configData.Token && configData.URL);\n } catch {\n return false;\n }\n }\n\n /** Redeems exactly once, converting any throw into the error state */\n private async safeRedeem(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.redeemClaim();\n } catch (error) {\n console.error('[Claim Redeem] Error redeeming claim:', error);\n this.showError(error instanceof Error ? error.message : String(error));\n }\n }\n\n /** Reads the query params and calls the redemption mutation */\n private async redeemClaim(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n const claimId = params['id'] as string | undefined;\n const token = params['token'] as string | undefined;\n\n if (!claimId) {\n this.showError('This link is missing its claim id. Please use the exact link from your email.');\n return;\n }\n\n this.StatusMessage = 'Redeeming your claim...';\n this.cdr.detectChanges();\n\n const provider = this.ProviderToUse as GraphQLDataProvider;\n const result = (await provider.ExecuteGQL(REDEEM_MUTATION, {\n ClaimID: claimId,\n Token: token ?? null\n })) as RedeemIdentityClaimResponse;\n\n const outcome = result?.RedeemIdentityClaim;\n if (outcome?.Success) {\n this.IsLoading = false;\n this.StatusMessage = 'Your claim has been redeemed and attached to your account.';\n this.cdr.detectChanges();\n } else {\n this.showError(outcome?.ErrorMessage || 'The claim could not be redeemed.');\n }\n }\n\n /** Shows the terminal error state */\n private showError(message: string): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorMessage = message;\n this.cdr.detectChanges();\n }\n\n /** Navigates into the app shell (which handles sign-in when needed) */\n public onGoToApp(): void {\n this.router.navigateByUrl('/');\n }\n\n /** Retries redemption from scratch (fresh component state) */\n public onRetry(): void {\n this.IsLoading = true;\n this.HasError = false;\n this.NeedsSignIn = false;\n this.ErrorMessage = '';\n this.isProcessing = false;\n void this.waitForProviderAndRedeem();\n }\n}\n","<div class=\"claim-redeem-container\">\n <div class=\"claim-redeem-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"claim-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"claim-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>{{ NeedsSignIn ? 'Sign In Required' : 'Claim Not Redeemed' }}</h2>\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (!NeedsSignIn) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"NeedsSignIn ? 'primary' : 'outline'\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n {{ NeedsSignIn ? 'Go to Sign In' : 'Open the App' }}\n </button>\n </div>\n </div>\n }\n\n <!-- Success State -->\n @if (!IsLoading && !HasError) {\n <div class=\"claim-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Claim Redeemed</h2>\n <p>{{ StatusMessage }}</p>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-house\"></i>\n Open the App\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"claim-redeem.component.js","sourceRoot":"","sources":["../../../src/lib/identity-claims/claim-redeem.component.ts","../../../src/lib/identity-claims/claim-redeem.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Identity Claim Redemption Page\n *\n * Landing page for the links in identity-claim emails\n * (`${PORTAL_BASE_URL}/claims/redeem?id=<claimId>&token=<rawToken>`). When a recipient\n * clicks through, this component:\n * 1. Waits for the user's session to be restored (same posture as the OAuth callback —\n * no AuthGuard; the component handles the not-yet-authenticated case itself)\n * 2. Extracts the claim id and optional verification token from the query params\n * 3. Calls the `RedeemIdentityClaim` GraphQL mutation, which runs the server engine's full\n * gate (email match subject to verification rules, or timing-safe token match, atomic CAS)\n * 4. Shows the outcome and offers navigation back into the app\n *\n * Like the OAuth callback, this is a deliberate exception to the NavigationService-only rule:\n * it is registered directly in the routing module and reads its own query params.\n *\n * @module IdentityClaims\n */\n\nimport { Component, OnDestroy, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\ninterface RedeemIdentityClaimResponse {\n RedeemIdentityClaim?: {\n Success: boolean;\n ErrorMessage?: string;\n ClaimID?: string;\n Data?: string;\n };\n}\n\n/** Maximum time to wait for session restoration (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\nconst REDEEM_MUTATION = `\n mutation RedeemIdentityClaim($ClaimID: String!, $Token: String) {\n RedeemIdentityClaim(ClaimID: $ClaimID, Token: $Token) {\n Success\n ErrorMessage\n ClaimID\n Data\n }\n }\n`;\n\n@Component({\n standalone: false,\n selector: 'mj-claim-redeem',\n templateUrl: './claim-redeem.component.html',\n styleUrls: ['./claim-redeem.component.css']\n})\nexport class ClaimRedeemComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /** Loading state while restoring the session / redeeming */\n public IsLoading = true;\n\n /** Terminal error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** True when the wait for authentication timed out (user likely not signed in) */\n public NeedsSignIn = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n await this.waitForProviderAndRedeem();\n }\n\n ngOnDestroy(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete),\n * then redeems the claim from the query params.\n */\n private async waitForProviderAndRedeem(): Promise<void> {\n const startTime = Date.now();\n\n if (this.isProviderReady()) {\n await this.safeRedeem();\n return;\n }\n\n this.StatusMessage = 'Waiting for sign-in...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeRedeem();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.NeedsSignIn = true;\n this.showError('Please sign in first, then open the link from your email again — the claim will attach to your signed-in account.');\n resolve();\n return;\n }\n\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for sign-in... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /** Checks if the GraphQL provider is initialized with a valid token */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n return Boolean(configData && configData.Token && configData.URL);\n } catch {\n return false;\n }\n }\n\n /** Redeems exactly once, converting any throw into the error state */\n private async safeRedeem(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.redeemClaim();\n } catch (error) {\n console.error('[Claim Redeem] Error redeeming claim:', error);\n this.showError(error instanceof Error ? error.message : String(error));\n }\n }\n\n /** Reads the query params and calls the redemption mutation */\n private async redeemClaim(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n const claimId = params['id'] as string | undefined;\n const token = params['token'] as string | undefined;\n\n if (!claimId) {\n this.showError('This link is missing its claim id. Please use the exact link from your email.');\n return;\n }\n\n this.StatusMessage = 'Redeeming your claim...';\n this.cdr.detectChanges();\n\n const provider = this.ProviderToUse as GraphQLDataProvider;\n const result = (await provider.ExecuteGQL(REDEEM_MUTATION, {\n ClaimID: claimId,\n Token: token ?? null\n })) as RedeemIdentityClaimResponse;\n\n const outcome = result?.RedeemIdentityClaim;\n if (outcome?.Success) {\n this.IsLoading = false;\n this.StatusMessage = 'Your claim has been redeemed and attached to your account.';\n this.cdr.detectChanges();\n } else {\n this.showError(outcome?.ErrorMessage || 'The claim could not be redeemed.');\n }\n }\n\n /** Shows the terminal error state */\n private showError(message: string): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorMessage = message;\n this.cdr.detectChanges();\n }\n\n /** Navigates into the app shell (which handles sign-in when needed) */\n public OnGoToApp(): void {\n this.router.navigateByUrl('/');\n }\n\n /** @deprecated Use {@link OnGoToApp}. */\n public onGoToApp(): void {\n return this.OnGoToApp();\n }\n\n /** Retries redemption from scratch (fresh component state) */\n public OnRetry(): void {\n this.IsLoading = true;\n this.HasError = false;\n this.NeedsSignIn = false;\n this.ErrorMessage = '';\n this.isProcessing = false;\n void this.waitForProviderAndRedeem();\n }\n\n /** @deprecated Use {@link OnRetry}. */\n public onRetry(): void {\n return this.OnRetry();\n }\n}\n","<div class=\"claim-redeem-container\">\n <div class=\"claim-redeem-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"claim-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"claim-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>{{ NeedsSignIn ? 'Sign In Required' : 'Claim Not Redeemed' }}</h2>\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (!NeedsSignIn) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"NeedsSignIn ? 'primary' : 'outline'\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n {{ NeedsSignIn ? 'Go to Sign In' : 'Open the App' }}\n </button>\n </div>\n </div>\n }\n\n <!-- Success State -->\n @if (!IsLoading && !HasError) {\n <div class=\"claim-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Claim Redeemed</h2>\n <p>{{ StatusMessage }}</p>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-house\"></i>\n Open the App\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n"]}
|
|
@@ -87,10 +87,14 @@ export declare class OAuthCallbackComponent extends BaseAngularComponent impleme
|
|
|
87
87
|
/**
|
|
88
88
|
* Handle retry button click
|
|
89
89
|
*/
|
|
90
|
+
OnRetry(): void;
|
|
91
|
+
/** @deprecated Use {@link OnRetry}. */
|
|
90
92
|
onRetry(): void;
|
|
91
93
|
/**
|
|
92
94
|
* Handle close button click (return to MCP dashboard)
|
|
93
95
|
*/
|
|
96
|
+
OnClose(): void;
|
|
97
|
+
/** @deprecated Use {@link OnClose}. */
|
|
94
98
|
onClose(): void;
|
|
95
99
|
static ɵfac: i0.ɵɵFactoryDeclaration<OAuthCallbackComponent, never>;
|
|
96
100
|
static ɵcmp: i0.ɵɵComponentDeclaration<OAuthCallbackComponent, "mj-oauth-callback", never, {}, {}, never, never, false, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-callback.component.d.ts","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAiBrE;;;;;;;;;GASG;AACH,qBAMa,sBAAuB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IA0BrF,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IA3Bf,oDAAoD;IAC7C,SAAS,UAAQ;IAExB,kBAAkB;IACX,QAAQ,UAAS;IAExB,+BAA+B;IACxB,YAAY,SAAM;IAEzB,iDAAiD;IAC1C,SAAS,SAAM;IAEtB,qCAAqC;IAC9B,WAAW,UAAS;IAE3B,6CAA6C;IACtC,aAAa,SAA0B;IAE9C,2CAA2C;IAC3C,OAAO,CAAC,SAAS,CAA+C;IAEhE,wCAAwC;IACxC,OAAO,CAAC,YAAY,CAAS;gBAGjB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,iBAAiB;IAI5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,WAAW,IAAI,IAAI;IAQnB;;;OAGG;YACW,yBAAyB;IAiDvC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;YACW,mBAAmB;IAcjC;;OAEG;YACW,oBAAoB;IAgDlC;;OAEG;YACW,YAAY;IAqC1B;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACI,OAAO,IAAI,IAAI;IAOtB;;OAEG;IACI,OAAO,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"oauth-callback.component.d.ts","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAiBrE;;;;;;;;;GASG;AACH,qBAMa,sBAAuB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IA0BrF,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IA3Bf,oDAAoD;IAC7C,SAAS,UAAQ;IAExB,kBAAkB;IACX,QAAQ,UAAS;IAExB,+BAA+B;IACxB,YAAY,SAAM;IAEzB,iDAAiD;IAC1C,SAAS,SAAM;IAEtB,qCAAqC;IAC9B,WAAW,UAAS;IAE3B,6CAA6C;IACtC,aAAa,SAA0B;IAE9C,2CAA2C;IAC3C,OAAO,CAAC,SAAS,CAA+C;IAEhE,wCAAwC;IACxC,OAAO,CAAC,YAAY,CAAS;gBAGjB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,iBAAiB;IAI5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,WAAW,IAAI,IAAI;IAQnB;;;OAGG;YACW,yBAAyB;IAiDvC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;YACW,mBAAmB;IAcjC;;OAEG;YACW,oBAAoB;IAgDlC;;OAEG;YACW,YAAY;IAqC1B;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACI,OAAO,IAAI,IAAI;IAOtB,uCAAuC;IAChC,OAAO,IAAI,IAAI;IAItB;;OAEG;IACI,OAAO,IAAI,IAAI;IAKtB,uCAAuC;IAChC,OAAO,IAAI,IAAI;yCAnVb,sBAAsB;2CAAtB,sBAAsB;CAsVlC"}
|
|
@@ -372,19 +372,27 @@ export class OAuthCallbackComponent extends BaseAngularComponent {
|
|
|
372
372
|
/**
|
|
373
373
|
* Handle retry button click
|
|
374
374
|
*/
|
|
375
|
-
|
|
375
|
+
OnRetry() {
|
|
376
376
|
// Get the stored return URL and redirect there to start fresh
|
|
377
377
|
const returnUrl = localStorage.getItem('oauth_return_url') || '/app/admin/MCP';
|
|
378
378
|
this.clearStoredReturnUrls();
|
|
379
379
|
this.router.navigateByUrl(returnUrl);
|
|
380
380
|
}
|
|
381
|
+
/** @deprecated Use {@link OnRetry}. */
|
|
382
|
+
onRetry() {
|
|
383
|
+
return this.OnRetry();
|
|
384
|
+
}
|
|
381
385
|
/**
|
|
382
386
|
* Handle close button click (return to MCP dashboard)
|
|
383
387
|
*/
|
|
384
|
-
|
|
388
|
+
OnClose() {
|
|
385
389
|
this.clearStoredReturnUrls();
|
|
386
390
|
this.router.navigate(['/app/admin/MCP']);
|
|
387
391
|
}
|
|
392
|
+
/** @deprecated Use {@link OnClose}. */
|
|
393
|
+
onClose() {
|
|
394
|
+
return this.OnClose();
|
|
395
|
+
}
|
|
388
396
|
static ɵfac = function OAuthCallbackComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || OAuthCallbackComponent)(i0.ɵɵdirectiveInject(i1.ActivatedRoute), i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
389
397
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: OAuthCallbackComponent, selectors: [["mj-oauth-callback"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 3, consts: [[1, "oauth-callback-container"], [1, "oauth-callback-card"], [1, "oauth-status", "loading"], [1, "oauth-status", "error"], [1, "oauth-status", "success"], [3, "text"], [1, "icon-container", "error-icon"], [1, "fa-solid", "fa-circle-exclamation"], [1, "error-code"], [1, "error-message"], [1, "button-group"], ["mjButton", "", "variant", "secondary"], ["mjButton", "", 3, "click", "variant"], [1, "fa-solid", "fa-arrow-left"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "icon-container", "success-icon"], [1, "fa-solid", "fa-circle-check"]], template: function OAuthCallbackComponent_Template(rf, ctx) { if (rf & 1) {
|
|
390
398
|
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-callback.component.js","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts","../../../src/lib/oauth/oauth-callback.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview OAuth Callback Component\n *\n * Handles OAuth provider redirects in the frontend. When an OAuth provider\n * redirects back to the application after user authorization, this component:\n * 1. Waits for the user's session to be restored (authentication)\n * 2. Extracts the code and state from URL query parameters\n * 3. Calls the backend /oauth/exchange endpoint to complete the token exchange\n * 4. Redirects to the original page with success/error notification\n *\n * @module OAuth Callback\n */\n\nimport { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Metadata } from '@memberjunction/core';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n/**\n * Response from the OAuth exchange endpoint\n */\ninterface OAuthExchangeResponse {\n success: boolean;\n connectionId?: string;\n errorCode?: string;\n errorMessage?: string;\n isRetryable?: boolean;\n}\n\n/** Maximum time to wait for provider initialization (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\n/**\n * OAuth Callback Component\n *\n * Handles the redirect from OAuth providers after user authorization.\n * This component is loaded at /oauth/callback and processes the\n * authorization code to complete the OAuth flow.\n *\n * The component waits for authentication to complete before attempting\n * the code exchange, since the user's session needs to be restored first.\n */\n@Component({\n standalone: false,\n selector: 'mj-oauth-callback',\n templateUrl: './oauth-callback.component.html',\n styleUrls: ['./oauth-callback.component.css']\n})\nexport class OAuthCallbackComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /** Loading state while processing OAuth callback */\n public IsLoading = true;\n\n /** Error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** Error code from OAuth provider or exchange */\n public ErrorCode = '';\n\n /** Whether the error is retryable */\n public IsRetryable = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {\n super();}\n\n async ngOnInit(): Promise<void> {\n // Wait for the GraphQL provider to be ready, then process the callback\n await this.waitForProviderAndProcess();\n }\n\n ngOnDestroy(): void {\n // Clean up the polling timer\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete)\n * then processes the OAuth callback.\n */\n private async waitForProviderAndProcess(): Promise<void> {\n const startTime = Date.now();\n\n // Check if provider is already ready\n if (this.isProviderReady()) {\n await this.safeProcessCallback();\n return;\n }\n\n // Poll for provider readiness\n this.StatusMessage = 'Waiting for authentication...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeProcessCallback();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.showError(\n 'timeout',\n 'Timed out waiting for authentication. Please try logging in again.',\n true\n );\n resolve();\n return;\n }\n\n // Update status message with progress\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for authentication... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /**\n * Checks if the GraphQL provider is initialized and has a valid token\n */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n if (!configData || !configData.Token || !configData.URL) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Safely processes the callback, preventing double execution\n */\n private async safeProcessCallback(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.processOAuthCallback();\n } catch (error) {\n console.error('[OAuth Callback] Error in processOAuthCallback:', error);\n this.showError('component_error', error instanceof Error ? error.message : String(error), true);\n }\n }\n\n /**\n * Process the OAuth callback by extracting params and exchanging the code\n */\n private async processOAuthCallback(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n\n // Check for error from OAuth provider\n if (params['error']) {\n this.showError(\n params['error'] as string,\n params['error_description'] as string || 'Authorization was denied or failed'\n );\n return;\n }\n\n const code = params['code'] as string;\n const state = params['state'] as string;\n\n // Validate required parameters\n if (!code) {\n this.showError('missing_code', 'No authorization code received from the OAuth provider');\n return;\n }\n\n if (!state) {\n this.showError('missing_state', 'No state parameter received from the OAuth provider');\n return;\n }\n\n // Exchange the code for tokens\n this.StatusMessage = 'Exchanging authorization code...';\n this.cdr.detectChanges();\n\n try {\n const result = await this.exchangeCode(code, state);\n\n if (result.success) {\n this.handleSuccess(result.connectionId);\n } else {\n this.showError(\n result.errorCode || 'exchange_failed',\n result.errorMessage || 'Failed to complete authorization',\n result.isRetryable\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.showError('network_error', message, true);\n }\n }\n\n /**\n * Call the backend to exchange the authorization code for tokens\n */\n private async exchangeCode(code: string, state: string): Promise<OAuthExchangeResponse> {\n // Get the GraphQL provider - we know it's ready at this point\n const gqlProvider = this.ProviderToUse as GraphQLDataProvider;\n const configData = gqlProvider.ConfigData;\n\n // Build the exchange endpoint URL from the GraphQL URL\n // Handle both cases: URL with /graphql suffix and URL without\n let apiUrl = configData.URL;\n if (apiUrl.includes('/graphql')) {\n apiUrl = apiUrl.replace('/graphql', '/oauth/exchange');\n } else {\n // URL doesn't have /graphql, append /oauth/exchange\n apiUrl = apiUrl.replace(/\\/$/, '') + '/oauth/exchange';\n }\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${configData.Token}`\n },\n body: JSON.stringify({ code, state })\n });\n\n // Parse response regardless of status code\n const data = await response.json();\n return data as OAuthExchangeResponse;\n } catch (fetchError) {\n return {\n success: false,\n errorCode: 'fetch_error',\n errorMessage: fetchError instanceof Error ? fetchError.message : 'Network error during token exchange'\n };\n }\n }\n\n /**\n * Handle successful OAuth completion\n */\n private handleSuccess(connectionId?: string): void {\n this.IsLoading = false;\n this.StatusMessage = 'Authorization successful! Redirecting...';\n this.cdr.detectChanges();\n\n // Get the stored return URL - try both localStorage and sessionStorage\n const storedUrl = localStorage.getItem('oauth_return_url');\n const storedPath = localStorage.getItem('oauth_return_path');\n const sessionUrl = sessionStorage.getItem('oauth_return_url');\n const sessionPath = sessionStorage.getItem('oauth_return_path');\n\n let returnUrl = storedUrl || sessionUrl || storedPath || sessionPath;\n\n // Clean up all possible storage locations\n this.clearStoredReturnUrls();\n\n // Default to MCP dashboard if no return URL found\n const defaultPath = '/app/admin/MCP';\n if (!returnUrl || returnUrl.trim() === '' || returnUrl === '/') {\n returnUrl = defaultPath;\n }\n\n // Build the final navigation path\n const finalPath = this.buildFinalPath(returnUrl, connectionId, defaultPath);\n\n // Use window.location for reliable navigation after OAuth\n setTimeout(() => {\n window.location.href = finalPath;\n }, 500);\n }\n\n /**\n * Builds the final navigation path with success query params\n */\n private buildFinalPath(returnUrl: string, connectionId: string | undefined, defaultPath: string): string {\n try {\n let finalPath: string;\n\n // If it's a full URL, extract just the path and search\n if (returnUrl.startsWith('http://') || returnUrl.startsWith('https://')) {\n const url = new URL(returnUrl);\n finalPath = url.pathname + url.search;\n } else {\n finalPath = returnUrl;\n }\n\n // Ensure we have a valid path (not empty or just \"/\")\n if (!finalPath || finalPath.trim() === '' || finalPath === '/') {\n finalPath = defaultPath;\n }\n\n // Add success query params\n const separator = finalPath.includes('?') ? '&' : '?';\n finalPath = `${finalPath}${separator}oauth=success`;\n if (connectionId) {\n finalPath += `&connectionId=${connectionId}`;\n }\n\n return finalPath;\n } catch (e) {\n console.error('[OAuth Callback] Error parsing return URL:', e);\n return `${defaultPath}?oauth=success${connectionId ? `&connectionId=${connectionId}` : ''}`;\n }\n }\n\n /**\n * Clears all stored return URLs from storage\n */\n private clearStoredReturnUrls(): void {\n localStorage.removeItem('oauth_return_url');\n localStorage.removeItem('oauth_return_path');\n sessionStorage.removeItem('oauth_return_url');\n sessionStorage.removeItem('oauth_return_path');\n }\n\n /**\n * Show error state\n */\n private showError(errorCode: string, message: string, isRetryable = false): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorCode = errorCode;\n this.ErrorMessage = message;\n this.IsRetryable = isRetryable;\n this.cdr.detectChanges();\n }\n\n /**\n * Handle retry button click\n */\n public onRetry(): void {\n // Get the stored return URL and redirect there to start fresh\n const returnUrl = localStorage.getItem('oauth_return_url') || '/app/admin/MCP';\n this.clearStoredReturnUrls();\n this.router.navigateByUrl(returnUrl);\n }\n\n /**\n * Handle close button click (return to MCP dashboard)\n */\n public onClose(): void {\n this.clearStoredReturnUrls();\n this.router.navigate(['/app/admin/MCP']);\n }\n}\n","<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"IsRetryable ? 'outline' : 'secondary'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"oauth-callback.component.js","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts","../../../src/lib/oauth/oauth-callback.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview OAuth Callback Component\n *\n * Handles OAuth provider redirects in the frontend. When an OAuth provider\n * redirects back to the application after user authorization, this component:\n * 1. Waits for the user's session to be restored (authentication)\n * 2. Extracts the code and state from URL query parameters\n * 3. Calls the backend /oauth/exchange endpoint to complete the token exchange\n * 4. Redirects to the original page with success/error notification\n *\n * @module OAuth Callback\n */\n\nimport { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Metadata } from '@memberjunction/core';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n/**\n * Response from the OAuth exchange endpoint\n */\ninterface OAuthExchangeResponse {\n success: boolean;\n connectionId?: string;\n errorCode?: string;\n errorMessage?: string;\n isRetryable?: boolean;\n}\n\n/** Maximum time to wait for provider initialization (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\n/**\n * OAuth Callback Component\n *\n * Handles the redirect from OAuth providers after user authorization.\n * This component is loaded at /oauth/callback and processes the\n * authorization code to complete the OAuth flow.\n *\n * The component waits for authentication to complete before attempting\n * the code exchange, since the user's session needs to be restored first.\n */\n@Component({\n standalone: false,\n selector: 'mj-oauth-callback',\n templateUrl: './oauth-callback.component.html',\n styleUrls: ['./oauth-callback.component.css']\n})\nexport class OAuthCallbackComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /** Loading state while processing OAuth callback */\n public IsLoading = true;\n\n /** Error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** Error code from OAuth provider or exchange */\n public ErrorCode = '';\n\n /** Whether the error is retryable */\n public IsRetryable = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {\n super();}\n\n async ngOnInit(): Promise<void> {\n // Wait for the GraphQL provider to be ready, then process the callback\n await this.waitForProviderAndProcess();\n }\n\n ngOnDestroy(): void {\n // Clean up the polling timer\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete)\n * then processes the OAuth callback.\n */\n private async waitForProviderAndProcess(): Promise<void> {\n const startTime = Date.now();\n\n // Check if provider is already ready\n if (this.isProviderReady()) {\n await this.safeProcessCallback();\n return;\n }\n\n // Poll for provider readiness\n this.StatusMessage = 'Waiting for authentication...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeProcessCallback();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.showError(\n 'timeout',\n 'Timed out waiting for authentication. Please try logging in again.',\n true\n );\n resolve();\n return;\n }\n\n // Update status message with progress\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for authentication... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /**\n * Checks if the GraphQL provider is initialized and has a valid token\n */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n if (!configData || !configData.Token || !configData.URL) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Safely processes the callback, preventing double execution\n */\n private async safeProcessCallback(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.processOAuthCallback();\n } catch (error) {\n console.error('[OAuth Callback] Error in processOAuthCallback:', error);\n this.showError('component_error', error instanceof Error ? error.message : String(error), true);\n }\n }\n\n /**\n * Process the OAuth callback by extracting params and exchanging the code\n */\n private async processOAuthCallback(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n\n // Check for error from OAuth provider\n if (params['error']) {\n this.showError(\n params['error'] as string,\n params['error_description'] as string || 'Authorization was denied or failed'\n );\n return;\n }\n\n const code = params['code'] as string;\n const state = params['state'] as string;\n\n // Validate required parameters\n if (!code) {\n this.showError('missing_code', 'No authorization code received from the OAuth provider');\n return;\n }\n\n if (!state) {\n this.showError('missing_state', 'No state parameter received from the OAuth provider');\n return;\n }\n\n // Exchange the code for tokens\n this.StatusMessage = 'Exchanging authorization code...';\n this.cdr.detectChanges();\n\n try {\n const result = await this.exchangeCode(code, state);\n\n if (result.success) {\n this.handleSuccess(result.connectionId);\n } else {\n this.showError(\n result.errorCode || 'exchange_failed',\n result.errorMessage || 'Failed to complete authorization',\n result.isRetryable\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.showError('network_error', message, true);\n }\n }\n\n /**\n * Call the backend to exchange the authorization code for tokens\n */\n private async exchangeCode(code: string, state: string): Promise<OAuthExchangeResponse> {\n // Get the GraphQL provider - we know it's ready at this point\n const gqlProvider = this.ProviderToUse as GraphQLDataProvider;\n const configData = gqlProvider.ConfigData;\n\n // Build the exchange endpoint URL from the GraphQL URL\n // Handle both cases: URL with /graphql suffix and URL without\n let apiUrl = configData.URL;\n if (apiUrl.includes('/graphql')) {\n apiUrl = apiUrl.replace('/graphql', '/oauth/exchange');\n } else {\n // URL doesn't have /graphql, append /oauth/exchange\n apiUrl = apiUrl.replace(/\\/$/, '') + '/oauth/exchange';\n }\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${configData.Token}`\n },\n body: JSON.stringify({ code, state })\n });\n\n // Parse response regardless of status code\n const data = await response.json();\n return data as OAuthExchangeResponse;\n } catch (fetchError) {\n return {\n success: false,\n errorCode: 'fetch_error',\n errorMessage: fetchError instanceof Error ? fetchError.message : 'Network error during token exchange'\n };\n }\n }\n\n /**\n * Handle successful OAuth completion\n */\n private handleSuccess(connectionId?: string): void {\n this.IsLoading = false;\n this.StatusMessage = 'Authorization successful! Redirecting...';\n this.cdr.detectChanges();\n\n // Get the stored return URL - try both localStorage and sessionStorage\n const storedUrl = localStorage.getItem('oauth_return_url');\n const storedPath = localStorage.getItem('oauth_return_path');\n const sessionUrl = sessionStorage.getItem('oauth_return_url');\n const sessionPath = sessionStorage.getItem('oauth_return_path');\n\n let returnUrl = storedUrl || sessionUrl || storedPath || sessionPath;\n\n // Clean up all possible storage locations\n this.clearStoredReturnUrls();\n\n // Default to MCP dashboard if no return URL found\n const defaultPath = '/app/admin/MCP';\n if (!returnUrl || returnUrl.trim() === '' || returnUrl === '/') {\n returnUrl = defaultPath;\n }\n\n // Build the final navigation path\n const finalPath = this.buildFinalPath(returnUrl, connectionId, defaultPath);\n\n // Use window.location for reliable navigation after OAuth\n setTimeout(() => {\n window.location.href = finalPath;\n }, 500);\n }\n\n /**\n * Builds the final navigation path with success query params\n */\n private buildFinalPath(returnUrl: string, connectionId: string | undefined, defaultPath: string): string {\n try {\n let finalPath: string;\n\n // If it's a full URL, extract just the path and search\n if (returnUrl.startsWith('http://') || returnUrl.startsWith('https://')) {\n const url = new URL(returnUrl);\n finalPath = url.pathname + url.search;\n } else {\n finalPath = returnUrl;\n }\n\n // Ensure we have a valid path (not empty or just \"/\")\n if (!finalPath || finalPath.trim() === '' || finalPath === '/') {\n finalPath = defaultPath;\n }\n\n // Add success query params\n const separator = finalPath.includes('?') ? '&' : '?';\n finalPath = `${finalPath}${separator}oauth=success`;\n if (connectionId) {\n finalPath += `&connectionId=${connectionId}`;\n }\n\n return finalPath;\n } catch (e) {\n console.error('[OAuth Callback] Error parsing return URL:', e);\n return `${defaultPath}?oauth=success${connectionId ? `&connectionId=${connectionId}` : ''}`;\n }\n }\n\n /**\n * Clears all stored return URLs from storage\n */\n private clearStoredReturnUrls(): void {\n localStorage.removeItem('oauth_return_url');\n localStorage.removeItem('oauth_return_path');\n sessionStorage.removeItem('oauth_return_url');\n sessionStorage.removeItem('oauth_return_path');\n }\n\n /**\n * Show error state\n */\n private showError(errorCode: string, message: string, isRetryable = false): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorCode = errorCode;\n this.ErrorMessage = message;\n this.IsRetryable = isRetryable;\n this.cdr.detectChanges();\n }\n\n /**\n * Handle retry button click\n */\n public OnRetry(): void {\n // Get the stored return URL and redirect there to start fresh\n const returnUrl = localStorage.getItem('oauth_return_url') || '/app/admin/MCP';\n this.clearStoredReturnUrls();\n this.router.navigateByUrl(returnUrl);\n }\n\n /** @deprecated Use {@link OnRetry}. */\n public onRetry(): void {\n return this.OnRetry();\n }\n\n /**\n * Handle close button click (return to MCP dashboard)\n */\n public OnClose(): void {\n this.clearStoredReturnUrls();\n this.router.navigate(['/app/admin/MCP']);\n }\n\n /** @deprecated Use {@link OnClose}. */\n public onClose(): void {\n return this.OnClose();\n }\n}\n","<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"IsRetryable ? 'outline' : 'secondary'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/lib/profile/profile-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,YAAY,EAEZ,SAAS,EACT,MAAM,EAIT,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAQrE,UAAU,mBAAmB;IACzB,GAAG,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,gBAAgB;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,KAAK,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/C;;;;GAIG;AACH,
|
|
1
|
+
{"version":3,"file":"profile-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/lib/profile/profile-dialog.component.ts"],"names":[],"mappings":"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"}
|