Extract session passwords from URL hash parameters for secure automatic session joining.
getSessionPasswordFromUrl
utility function extracts the session password from a URL’s hash parameters. Hash parameters are used for passwords because they are not sent to servers in HTTP requests, providing better security for sensitive session credentials while still enabling automatic session joining from shared links.
import { utils } from 'react-together'
const { getSessionPasswordFromUrl } = utils
getSessionPasswordFromUrl(
url: URL,
options?: {
passwordKey?: string
}
): string | null
null
if it does not exist in the URL hashimport { utils } from 'react-together'
const { getSessionPasswordFromUrl } = utils
function parsePasswordFromUrl() {
// URL with default password parameter in hash
const url = new URL('https://myapp.com/collaborate?rtName=session#rtPwd=secure123')
const password = getSessionPasswordFromUrl(url)
console.log(password)
// Output: "secure123"
return password
}
// Example with no password parameter
function parseUrlWithoutPassword() {
const url = new URL('https://myapp.com/collaborate?rtName=session')
const password = getSessionPasswordFromUrl(url)
console.log(password)
// Output: null
return password
}
import { utils } from 'react-together'
const { getSessionPasswordFromUrl } = utils
function parseCustomPasswordParameter() {
// URL with custom password parameter
const url = new URL('https://myapp.com/rooms?roomId=meeting#access=secretToken123')
const password = getSessionPasswordFromUrl(url, { passwordKey: 'access' })
console.log(password)
// Output: "secretToken123"
return password
}
import { utils } from 'react-together'
import { useState, useEffect } from 'react'
const { getSessionNameFromUrl, getSessionPasswordFromUrl } = utils
interface SessionCredentials {
name: string
password: string
isValid: boolean
}
function SecureSessionAuthenticator() {
const [credentials, setCredentials] = useState<SessionCredentials | null>(null)
const [authStatus, setAuthStatus] = useState<'checking' | 'valid' | 'invalid' | 'missing'>('checking')
useEffect(() => {
const authenticateFromUrl = async () => {
const currentUrl = new URL(window.location.href)
const sessionName = getSessionNameFromUrl(currentUrl)
const sessionPassword = getSessionPasswordFromUrl(currentUrl)
if (!sessionName || !sessionPassword) {
setAuthStatus('missing')
return
}
// Validate password strength
if (sessionPassword.length < 6) {
setAuthStatus('invalid')
return
}
// Here you would typically validate against your backend
const isValidCredentials = await validateSessionCredentials(sessionName, sessionPassword)
if (isValidCredentials) {
setCredentials({
name: sessionName,
password: sessionPassword,
isValid: true
})
setAuthStatus('valid')
} else {
setAuthStatus('invalid')
}
}
authenticateFromUrl()
}, [])
const validateSessionCredentials = async (name: string, password: string): Promise<boolean> => {
// Simulate API call for credential validation
return new Promise(resolve => {
setTimeout(() => {
// Simple validation logic (replace with real validation)
resolve(password.length >= 6 && name.length > 0)
}, 1000)
})
}
if (authStatus === 'checking') {
return (
<div className="auth-checking">
<div className="spinner"></div>
<p>Validating session credentials...</p>
</div>
)
}
if (authStatus === 'missing') {
return (
<div className="auth-missing">
<h3>🔑 Session Credentials Required</h3>
<p>This URL does not contain valid session credentials.</p>
<button>Create New Session</button>
</div>
)
}
if (authStatus === 'invalid') {
return (
<div className="auth-invalid">
<h3>❌ Invalid Credentials</h3>
<p>The session credentials in this URL are invalid or expired.</p>
<button>Try Different Session</button>
</div>
)
}
return (
<div className="auth-valid">
<h3>✅ Session Authenticated</h3>
<p>Successfully authenticated for session: <strong>{credentials?.name}</strong></p>
<button>Join Session</button>
</div>
)
}
import { utils } from 'react-together'
const { getSessionPasswordFromUrl } = utils
interface PasswordValidation {
isValid: boolean
strength: 'weak' | 'medium' | 'strong'
issues: string[]
suggestions: string[]
}
function validatePasswordSecurity(password: string): PasswordValidation {
const issues: string[] = []
const suggestions: string[] = []
// Length check
if (password.length < 6) {
issues.push('Password too short')
suggestions.push('Use at least 6 characters')
}
if (password.length < 8) {
suggestions.push('Consider using 8+ characters for better security')
}
// Character variety checks
if (!/[a-z]/.test(password)) {
issues.push('No lowercase letters')
suggestions.push('Include lowercase letters')
}
if (!/[A-Z]/.test(password)) {
issues.push('No uppercase letters')
suggestions.push('Include uppercase letters')
}
if (!/[0-9]/.test(password)) {
issues.push('No numbers')
suggestions.push('Include numbers')
}
if (!/[^a-zA-Z0-9]/.test(password)) {
suggestions.push('Consider adding special characters')
}
// Common password check
const commonPasswords = ['password', '123456', 'qwerty', 'abc123']
if (commonPasswords.includes(password.toLowerCase())) {
issues.push('Common password detected')
suggestions.push('Use a unique password')
}
// Determine strength
let strength: 'weak' | 'medium' | 'strong' = 'weak'
if (issues.length === 0) {
if (password.length >= 12 && /[^a-zA-Z0-9]/.test(password)) {
strength = 'strong'
} else if (password.length >= 8) {
strength = 'medium'
}
}
return {
isValid: issues.length === 0,
strength,
issues,
suggestions
}
}
function PasswordSecurityChecker() {
const [urlInput, setUrlInput] = useState('')
const [passwordValidation, setPasswordValidation] = useState<PasswordValidation | null>(null)
const [extractedPassword, setExtractedPassword] = useState<string | null>(null)
const checkPasswordSecurity = () => {
try {
const url = new URL(urlInput)
const password = getSessionPasswordFromUrl(url)
if (password) {
setExtractedPassword(password)
const validation = validatePasswordSecurity(password)
setPasswordValidation(validation)
} else {
setExtractedPassword(null)
setPasswordValidation(null)
}
} catch (error) {
console.error('Invalid URL:', error)
setExtractedPassword(null)
setPasswordValidation(null)
}
}
return (
<div className="password-security-checker">
<h3>🔐 Password Security Checker</h3>
<p>Check the security of passwords in session URLs</p>
<div className="checker-input">
<textarea
value={urlInput}
onChange={(e) => setUrlInput(e.target.value)}
placeholder="Paste session URL here..."
rows={3}
/>
<button onClick={checkPasswordSecurity}>
Check Password Security
</button>
</div>
{extractedPassword && (
<div className="password-info">
<h4>Extracted Password</h4>
<div className="password-display">
<code>{'*'.repeat(extractedPassword.length)}</code>
<small>Length: {extractedPassword.length} characters</small>
</div>
</div>
)}
{passwordValidation && (
<div className="validation-results">
<div className={`strength-indicator ${passwordValidation.strength}`}>
<h4>Security Strength: {passwordValidation.strength.toUpperCase()}</h4>
<div className={`strength-bar ${passwordValidation.strength}`}>
<div className="strength-fill"></div>
</div>
</div>
{passwordValidation.issues.length > 0 && (
<div className="security-issues">
<h5>🚨 Security Issues</h5>
<ul>
{passwordValidation.issues.map((issue, index) => (
<li key={index} className="issue">{issue}</li>
))}
</ul>
</div>
)}
{passwordValidation.suggestions.length > 0 && (
<div className="security-suggestions">
<h5>💡 Suggestions</h5>
<ul>
{passwordValidation.suggestions.map((suggestion, index) => (
<li key={index} className="suggestion">{suggestion}</li>
))}
</ul>
</div>
)}
<div className={`validity-status ${passwordValidation.isValid ? 'valid' : 'invalid'}`}>
{passwordValidation.isValid ?
'✅ Password meets minimum security requirements' :
'❌ Password does not meet security requirements'
}
</div>
</div>
)}
</div>
)
}
import { utils } from 'react-together'
import { useState } from 'react'
const { getJoinUrl, getSessionPasswordFromUrl } = utils
function SecureUrlBuilder() {
const [sessionName, setSessionName] = useState('')
const [password, setPassword] = useState('')
const [generatedUrl, setGeneratedUrl] = useState<string | null>(null)
const [passwordStrength, setPasswordStrength] = useState<'weak' | 'medium' | 'strong'>('weak')
const generateSecurePassword = () => {
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
let result = ''
for (let i = 0; i < 12; i++) {
result += charset.charAt(Math.floor(Math.random() * charset.length))
}
setPassword(result)
setPasswordStrength('strong')
}
const evaluatePasswordStrength = (pwd: string) => {
if (pwd.length < 6) return 'weak'
if (pwd.length < 8 || !/[A-Z]/.test(pwd) || !/[0-9]/.test(pwd)) return 'weak'
if (pwd.length < 10 || !/[^a-zA-Z0-9]/.test(pwd)) return 'medium'
return 'strong'
}
const handlePasswordChange = (newPassword: string) => {
setPassword(newPassword)
setPasswordStrength(evaluatePasswordStrength(newPassword))
}
const buildSecureUrl = () => {
if (!sessionName || !password) return
if (passwordStrength === 'weak') {
alert('Please use a stronger password for better security')
return
}
const baseUrl = new URL(window.location.origin + window.location.pathname)
const joinUrl = getJoinUrl(baseUrl, sessionName, password)
setGeneratedUrl(joinUrl.toString())
}
const testPasswordExtraction = () => {
if (!generatedUrl) return
const url = new URL(generatedUrl)
const extractedPassword = getSessionPasswordFromUrl(url)
if (extractedPassword === password) {
alert('✅ Password extraction successful!')
} else {
alert('❌ Password extraction failed')
}
}
return (
<div className="secure-url-builder">
<h3>🔒 Secure Session URL Builder</h3>
<div className="builder-form">
<div className="form-group">
<label>Session Name:</label>
<input
type="text"
value={sessionName}
onChange={(e) => setSessionName(e.target.value)}
placeholder="team-meeting-2024"
/>
</div>
<div className="form-group">
<label>Password:</label>
<div className="password-input">
<input
type="password"
value={password}
onChange={(e) => handlePasswordChange(e.target.value)}
placeholder="Enter secure password"
/>
<button onClick={generateSecurePassword} className="generate-btn">
Generate Strong Password
</button>
</div>
<div className={`strength-indicator ${passwordStrength}`}>
Strength: {passwordStrength.toUpperCase()}
</div>
</div>
<button
onClick={buildSecureUrl}
disabled={!sessionName || !password || passwordStrength === 'weak'}
className="build-btn"
>
Build Secure URL
</button>
</div>
{generatedUrl && (
<div className="url-result">
<h4>Generated Secure URL</h4>
<div className="url-display">
<textarea
value={generatedUrl}
readOnly
rows={3}
onClick={(e) => e.currentTarget.select()}
/>
</div>
<div className="url-actions">
<button onClick={() => navigator.clipboard.writeText(generatedUrl)}>
📋 Copy URL
</button>
<button onClick={testPasswordExtraction}>
🧪 Test Password Extraction
</button>
</div>
<div className="security-info">
<h5>🔐 Security Features</h5>
<ul>
<li>✅ Password stored in URL hash (not sent to servers)</li>
<li>✅ Strong password requirement enforced</li>
<li>✅ Secure parameter extraction</li>
</ul>
</div>
</div>
)}
</div>
)
}
import { utils } from 'react-together'
import { useState, useEffect } from 'react'
const { getSessionNameFromUrl, getSessionPasswordFromUrl } = utils
interface StoredSession {
id: string
sessionName: string
hashedPassword: string // Store hashed, not plain text
createdAt: Date
lastUsed: Date
usageCount: number
}
// Simple hash function (use a proper crypto library in production)
function simpleHash(text: string): string {
let hash = 0
for (let i = 0; i < text.length; i++) {
const char = text.charCodeAt(i)
hash = ((hash << 5) - hash) + char
hash = hash & hash // Convert to 32-bit integer
}
return hash.toString(36)
}
function SessionPasswordManager() {
const [storedSessions, setStoredSessions] = useState<StoredSession[]>([])
const [currentSession, setCurrentSession] = useState<{name: string, password: string} | null>(null)
useEffect(() => {
// Load stored sessions
const saved = localStorage.getItem('sessionPasswords')
if (saved) {
const parsed = JSON.parse(saved)
const sessions = parsed.map((session: any) => ({
...session,
createdAt: new Date(session.createdAt),
lastUsed: new Date(session.lastUsed)
}))
setStoredSessions(sessions)
}
// Check current URL for session
const currentUrl = new URL(window.location.href)
const sessionName = getSessionNameFromUrl(currentUrl)
const sessionPassword = getSessionPasswordFromUrl(currentUrl)
if (sessionName && sessionPassword) {
setCurrentSession({ name: sessionName, password: sessionPassword })
updateSessionUsage(sessionName, sessionPassword)
}
}, [])
const saveStoredSessions = (sessions: StoredSession[]) => {
setStoredSessions(sessions)
localStorage.setItem('sessionPasswords', JSON.stringify(sessions))
}
const updateSessionUsage = (sessionName: string, password: string) => {
const hashedPassword = simpleHash(password)
const existingIndex = storedSessions.findIndex(
session => session.sessionName === sessionName && session.hashedPassword === hashedPassword
)
if (existingIndex >= 0) {
// Update existing session
const updated = [...storedSessions]
updated[existingIndex] = {
...updated[existingIndex],
lastUsed: new Date(),
usageCount: updated[existingIndex].usageCount + 1
}
saveStoredSessions(updated)
} else {
// Add new session
const newSession: StoredSession = {
id: Math.random().toString(36).substr(2, 9),
sessionName,
hashedPassword,
createdAt: new Date(),
lastUsed: new Date(),
usageCount: 1
}
saveStoredSessions([newSession, ...storedSessions])
}
}
const removeStoredSession = (sessionId: string) => {
saveStoredSessions(storedSessions.filter(session => session.id !== sessionId))
}
const clearAllSessions = () => {
saveStoredSessions([])
}
return (
<div className="session-password-manager">
<div className="current-session">
<h3>🔓 Current Session</h3>
{currentSession ? (
<div className="session-info">
<p><strong>Session:</strong> {currentSession.name}</p>
<p><strong>Password:</strong> {'*'.repeat(currentSession.password.length)}</p>
<div className="session-actions">
<button>Leave Session</button>
<button>Share Session</button>
</div>
</div>
) : (
<p>No active session detected</p>
)}
</div>
<div className="stored-sessions">
<div className="sessions-header">
<h3>🗝️ Saved Sessions ({storedSessions.length})</h3>
<button onClick={clearAllSessions} className="clear-btn">
Clear All
</button>
</div>
{storedSessions.length === 0 ? (
<div className="empty-sessions">
<p>No saved sessions</p>
<small>Sessions you join will be remembered here</small>
</div>
) : (
<div className="sessions-list">
{storedSessions.map(session => (
<div key={session.id} className="session-item">
<div className="session-details">
<h4>{session.sessionName}</h4>
<div className="session-meta">
<span>Used {session.usageCount} time{session.usageCount !== 1 ? 's' : ''}</span>
<span>Last: {session.lastUsed.toLocaleDateString()}</span>
</div>
</div>
<div className="session-actions">
<button className="rejoin-btn">
Rejoin
</button>
<button
onClick={() => removeStoredSession(session.id)}
className="remove-btn"
>
Remove
</button>
</div>
</div>
))}
</div>
)}
</div>
<div className="security-notice">
<h4>🔒 Security Information</h4>
<ul>
<li>Passwords are hashed before local storage</li>
<li>Hash parameters are not sent to servers</li>
<li>Session data is stored locally only</li>
<li>Clear your data regularly for maximum security</li>
</ul>
</div>
</div>
)
}
https://example.com/path?rtName=session#rtPwd=password123
↑
Password in hash (secure)
https://example.com/path?sessionId=meeting#token=secret123
↑
Custom password key
// ✅ Good - Password in hash (not sent to server)
const url = new URL('https://app.com?rtName=session#rtPwd=password')
const password = getSessionPasswordFromUrl(url)
// ❌ Bad - Password in query (sent to server)
const url = new URL('https://app.com?rtName=session&rtPwd=password')
// This would expose the password to server logs
// ✅ Good - Validate extracted passwords
const password = getSessionPasswordFromUrl(url)
if (password && password.length >= 6) {
// Use the password
}
// ✅ Good - Check password strength
const isStrongPassword = password &&
password.length >= 8 &&
/[A-Z]/.test(password) &&
/[0-9]/.test(password)
// ✅ Good - Hash passwords before storing locally
const hashedPassword = await crypto.subtle.digest('SHA-256',
new TextEncoder().encode(password)
)
// ❌ Bad - Storing plain text passwords
localStorage.setItem('password', password)
// Invalid URL - handled by URL constructor
const password = getSessionPasswordFromUrl(invalidUrl) // null
// Missing hash parameter
const url = new URL('https://app.com?rtName=session')
const password = getSessionPasswordFromUrl(url) // null
// Empty parameter value
const url = new URL('https://app.com#rtPwd=')
const password = getSessionPasswordFromUrl(url) // ""
// Custom parameter not found
const url = new URL('https://app.com#rtPwd=password')
const password = getSessionPasswordFromUrl(url, { passwordKey: 'missing' }) // null
// ✅ Good - Use strong passwords
const minPasswordLength = 8
const hasStrongPassword = password && password.length >= minPasswordLength
// ✅ Good - Validate before use
const password = getSessionPasswordFromUrl(url)
if (password && isValidPassword(password)) {
joinSession(sessionName, password)
}
// ✅ Good - Handle missing passwords gracefully
const password = getSessionPasswordFromUrl(url)
if (!password) {
showPasswordPrompt()
return
}
// ✅ Good - Always validate URLs first
try {
const url = new URL(urlString)
const password = getSessionPasswordFromUrl(url)
} catch (error) {
console.error('Invalid URL format:', error)
}
getSessionNameFromUrl
- Extract session namesgetJoinUrl
- Create URLs with session parametersgetCleanUrl
- Remove session parametersuseJoinUrl
- Get current session join URLuseCreateRandomSession
- Create new secure sessionsuseLeaveSession
- Leave sessions with credential cleanupimport { utils } from 'react-together'
const { getSessionPasswordFromUrl } = utils
// TypeScript will enforce correct parameter types
const password: string | null = getSessionPasswordFromUrl(
new URL('https://app.com#rtPwd=password'),
{ passwordKey: 'token' }
)