47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import { createHash, randomBytes } from 'crypto';
|
|
import type { SsoProvider } from './dto/sso-provider';
|
|
|
|
export function randomOpaqueToken(size = 32): string {
|
|
return randomBytes(size).toString('base64url');
|
|
}
|
|
|
|
export function sha256(value: string): string {
|
|
return createHash('sha256').update(value).digest('hex');
|
|
}
|
|
|
|
export function isLoopbackRedirect(value: string): boolean {
|
|
try {
|
|
const parsed = new URL(value);
|
|
return (
|
|
(parsed.protocol === 'http:' || parsed.protocol === 'https:') &&
|
|
['127.0.0.1', 'localhost'].includes(parsed.hostname)
|
|
);
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function asProviderName(value: SsoProvider): 'GOOGLE' | 'DISCORD' {
|
|
return value === 'google' ? 'GOOGLE' : 'DISCORD';
|
|
}
|
|
|
|
export function normalizeEmail(email: string): string {
|
|
return email.trim().toLowerCase();
|
|
}
|
|
|
|
export function normalizeUsername(value: string): string {
|
|
return value
|
|
.trim()
|
|
.toLowerCase()
|
|
.normalize('NFKD')
|
|
.replace(/[\u0300-\u036f]/g, '')
|
|
.replace(/[^a-z0-9]+/g, '_')
|
|
.replace(/^_+|_+$/g, '')
|
|
.slice(0, 24);
|
|
}
|
|
|
|
export function usernameFromEmail(email: string): string {
|
|
const localPart = normalizeEmail(email).split('@')[0] ?? '';
|
|
return normalizeUsername(localPart);
|
|
}
|