-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Fix account creation failures in insecure HTTP contexts #1267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
devdattatalele
wants to merge
3
commits into
simstudioai:main
Choose a base branch
from
devdattatalele:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+561
−50
Open
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,20 +3,105 @@ | |
| import { useEffect } from 'react' | ||
| import * as Sentry from '@sentry/nextjs' | ||
| import NextError from 'next/error' | ||
| import { createLogger } from '@/lib/logs/console/logger' | ||
|
|
||
| export default function GlobalError({ error }: { error: Error & { digest?: string } }) { | ||
| const logger = createLogger('GlobalError') | ||
|
|
||
| export default function GlobalError({ | ||
| error, | ||
| reset | ||
| }: { | ||
| error: Error & { digest?: string } | ||
| reset?: () => void | ||
| }) { | ||
| useEffect(() => { | ||
| // Enhanced error logging for debugging | ||
| logger.error('Global error occurred:', { | ||
| message: error.message, | ||
| name: error.name, | ||
| stack: error.stack, | ||
| digest: error.digest, | ||
| // Additional context for crypto-related errors | ||
| userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'N/A', | ||
| isSecureContext: typeof window !== 'undefined' ? window.isSecureContext : 'N/A', | ||
| location: typeof window !== 'undefined' ? window.location.href : 'N/A', | ||
| }) | ||
|
|
||
| // Check if this is a crypto-related error and provide specific guidance | ||
| if (error.message?.includes('randomUUID') || error.message?.includes('crypto')) { | ||
| logger.warn('Crypto API error detected. This may be due to insecure context (HTTP instead of HTTPS)') | ||
| } | ||
|
|
||
| Sentry.captureException(error) | ||
| }, [error]) | ||
|
|
||
| return ( | ||
| <html lang='en'> | ||
| <body> | ||
| {/* `NextError` is the default Next.js error page component. Its type | ||
| definition requires a `statusCode` prop. However, since the App Router | ||
| does not expose status codes for errors, we simply pass 0 to render a | ||
| generic error message. */} | ||
| <NextError statusCode={0} /> | ||
| <div style={{ | ||
| padding: '2rem', | ||
| textAlign: 'center', | ||
| fontFamily: 'system-ui, sans-serif', | ||
| minHeight: '100vh', | ||
| display: 'flex', | ||
| flexDirection: 'column', | ||
| justifyContent: 'center', | ||
| backgroundColor: '#1a1a1a', | ||
| color: '#white' | ||
| }}> | ||
| <h1 style={{ color: '#ef4444', marginBottom: '1rem' }}> | ||
| Application Error | ||
| </h1> | ||
| <p style={{ marginBottom: '1rem', color: '#a3a3a3' }}> | ||
| A client-side exception has occurred. This error has been logged for investigation. | ||
| </p> | ||
| {error.message?.includes('randomUUID') || error.message?.includes('crypto') ? ( | ||
| <div style={{ | ||
| backgroundColor: '#374151', | ||
| padding: '1rem', | ||
| borderRadius: '0.5rem', | ||
| marginBottom: '1rem', | ||
| color: '#fbbf24' | ||
| }}> | ||
| <p><strong>Tip:</strong> This error may be resolved by:</p> | ||
| <ul style={{ textAlign: 'left', margin: '0.5rem 0' }}> | ||
| <li>Accessing the application via HTTPS</li> | ||
| <li>Using localhost instead of other local IP addresses</li> | ||
| <li>Checking your browser security settings</li> | ||
| </ul> | ||
| </div> | ||
| ) : null} | ||
| {reset && ( | ||
| <button | ||
| onClick={reset} | ||
| style={{ | ||
| padding: '0.5rem 1rem', | ||
| backgroundColor: '#3b82f6', | ||
| color: 'white', | ||
| border: 'none', | ||
| borderRadius: '0.25rem', | ||
| cursor: 'pointer', | ||
| fontSize: '1rem' | ||
| }} | ||
| > | ||
| Try Again | ||
| </button> | ||
| )} | ||
| <details style={{ marginTop: '2rem', textAlign: 'left', maxWidth: '600px', margin: '2rem auto 0' }}> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: The margin override ('2rem auto 0') will overwrite the marginTop property set on the same line, consider using separate properties |
||
| <summary style={{ cursor: 'pointer', marginBottom: '1rem' }}>Error Details</summary> | ||
| <pre style={{ | ||
| backgroundColor: '#374151', | ||
| padding: '1rem', | ||
| borderRadius: '0.25rem', | ||
| overflow: 'auto', | ||
| fontSize: '0.8rem', | ||
| color: '#d1d5db' | ||
| }}> | ||
| {error.name}: {error.message} | ||
| {error.stack && `\n\nStack Trace:\n${error.stack}`} | ||
| </pre> | ||
| </details> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| ) | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| /** | ||
| * UUID utility that works in both secure and non-secure contexts | ||
| * Addresses the crypto.randomUUID() issue in insecure HTTP contexts | ||
| * | ||
| * SECURITY NOTE: The fallback Math.random() UUID is cryptographically weak | ||
| * and should not be used for security-sensitive operations (tokens, secrets, etc.). | ||
| * It is suitable for client-side UI state management, temporary IDs, and similar uses. | ||
| */ | ||
|
|
||
| /** | ||
| * Fallback UUID v4 generator using Math.random() | ||
| * This provides a cryptographically weak but acceptable UUID | ||
| * when crypto.randomUUID() is not available (insecure contexts) | ||
| */ | ||
| function fallbackUUIDv4(): string { | ||
| return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { | ||
| const r = (Math.random() * 16) | 0 | ||
| const v = c === 'x' ? r : (r & 0x3) | 0x8 | ||
| return v.toString(16) | ||
| }) | ||
| } | ||
|
|
||
| /** | ||
| * Check if we're running in a secure context where crypto.randomUUID() is available | ||
| * Defaults to true for older browsers that don't support window.isSecureContext | ||
| */ | ||
| function isSecureContext(): boolean { | ||
| return ( | ||
| typeof window !== 'undefined' && | ||
| (window.isSecureContext === undefined || window.isSecureContext) && // Default to true for older browsers | ||
| typeof crypto !== 'undefined' && | ||
| typeof crypto.randomUUID === 'function' | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Generate a UUID that works in both secure and insecure contexts | ||
| * - Uses crypto.randomUUID() in secure contexts (HTTPS, localhost) | ||
| * - Falls back to Math.random() based UUID in insecure contexts | ||
| * | ||
| * @returns A UUID v4 string | ||
| */ | ||
| export function generateUUID(): string { | ||
| try { | ||
| // Try to use crypto.randomUUID() first (secure context) | ||
| if (isSecureContext()) { | ||
| return crypto.randomUUID() | ||
| } | ||
| } catch (error) { | ||
| // crypto.randomUUID() not available or threw an error | ||
| console.warn('crypto.randomUUID() not available, falling back to Math.random() UUID generation') | ||
| } | ||
|
|
||
| // Fallback for insecure contexts or when crypto.randomUUID() is not available | ||
| return fallbackUUIDv4() | ||
| } | ||
|
|
||
| /** | ||
| * Server-side UUID generation using Node.js crypto module | ||
| * This is always secure and should be used for server-side code | ||
| */ | ||
| export function generateServerUUID(): string { | ||
| // This will use Node.js crypto.randomUUID() on the server | ||
| if (typeof globalThis !== 'undefined' && globalThis.crypto?.randomUUID) { | ||
| return globalThis.crypto.randomUUID() | ||
| } | ||
|
|
||
| // Fallback to Node.js crypto module if available | ||
| try { | ||
| const { randomUUID } = require('crypto') | ||
| return randomUUID() | ||
| } catch (error) { | ||
| console.warn('Node.js crypto module not available, using fallback UUID generation') | ||
| return fallbackUUIDv4() | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Context-aware UUID generation | ||
| * - Uses server-side crypto on the server | ||
| * - Uses client-side crypto or fallback on the client | ||
| */ | ||
| export function generateContextAwareUUID(): string { | ||
| if (typeof window === 'undefined') { | ||
| // Server-side | ||
| return generateServerUUID() | ||
| } else { | ||
| // Client-side | ||
| return generateUUID() | ||
| } | ||
| } | ||
|
|
||
| // Default export for easy migration | ||
| export default generateContextAwareUUID |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
syntax: Color value should be 'white' not '#white' - the hash prefix is incorrect for named colors