168 lines
2.3 KiB
TypeScript
168 lines
2.3 KiB
TypeScript
import { customAlphabet } from 'nanoid';
|
|
|
|
// Word lists for generating memorable tokens
|
|
const adjectives = [
|
|
'quick',
|
|
'lazy',
|
|
'happy',
|
|
'brave',
|
|
'bright',
|
|
'calm',
|
|
'clever',
|
|
'eager',
|
|
'gentle',
|
|
'kind',
|
|
'lively',
|
|
'proud',
|
|
'silly',
|
|
'witty',
|
|
'bold',
|
|
'cool',
|
|
'fair',
|
|
'fine',
|
|
'glad',
|
|
'good',
|
|
'neat',
|
|
'nice',
|
|
'rare',
|
|
'safe',
|
|
'warm',
|
|
'wise',
|
|
'fresh',
|
|
'clean',
|
|
'clear',
|
|
'crisp',
|
|
'sweet',
|
|
'smooth',
|
|
];
|
|
|
|
const colors = [
|
|
'red',
|
|
'blue',
|
|
'green',
|
|
'yellow',
|
|
'purple',
|
|
'orange',
|
|
'pink',
|
|
'black',
|
|
'white',
|
|
'gray',
|
|
'brown',
|
|
'cyan',
|
|
'lime',
|
|
'navy',
|
|
'teal',
|
|
'gold',
|
|
'silver',
|
|
'coral',
|
|
'salmon',
|
|
'indigo',
|
|
'violet',
|
|
'crimson',
|
|
'azure',
|
|
'jade',
|
|
];
|
|
|
|
const animals = [
|
|
'cat',
|
|
'dog',
|
|
'bird',
|
|
'fish',
|
|
'bear',
|
|
'lion',
|
|
'wolf',
|
|
'fox',
|
|
'deer',
|
|
'owl',
|
|
'hawk',
|
|
'duck',
|
|
'goat',
|
|
'seal',
|
|
'crab',
|
|
'moth',
|
|
'bee',
|
|
'ant',
|
|
'bat',
|
|
'cow',
|
|
'pig',
|
|
'hen',
|
|
'ram',
|
|
'rat',
|
|
'eel',
|
|
'cod',
|
|
'jay',
|
|
'yak',
|
|
'ox',
|
|
'pug',
|
|
'doe',
|
|
'hog',
|
|
];
|
|
|
|
const nouns = [
|
|
'moon',
|
|
'star',
|
|
'cloud',
|
|
'river',
|
|
'mountain',
|
|
'ocean',
|
|
'forest',
|
|
'desert',
|
|
'island',
|
|
'valley',
|
|
'meadow',
|
|
'garden',
|
|
'bridge',
|
|
'castle',
|
|
'tower',
|
|
'light',
|
|
'shadow',
|
|
'dream',
|
|
'hope',
|
|
'wish',
|
|
'song',
|
|
'dance',
|
|
'smile',
|
|
'laugh',
|
|
'gift',
|
|
'pearl',
|
|
'jewel',
|
|
'crown',
|
|
'shield',
|
|
'sword',
|
|
'arrow',
|
|
'bow',
|
|
];
|
|
|
|
// Generate a 4-digit number suffix for uniqueness
|
|
const generateNumber = customAlphabet('0123456789', 4);
|
|
|
|
function getRandomElement<T>(array: T[]): T {
|
|
return array[Math.floor(Math.random() * array.length)];
|
|
}
|
|
|
|
export function generateMemorableToken(): string {
|
|
const parts = [
|
|
getRandomElement(adjectives),
|
|
getRandomElement(colors),
|
|
getRandomElement(animals),
|
|
generateNumber(),
|
|
];
|
|
|
|
return parts.join('-');
|
|
}
|
|
|
|
export function generateShortToken(): string {
|
|
const parts = [getRandomElement(colors), getRandomElement(nouns), generateNumber()];
|
|
|
|
return parts.join('-');
|
|
}
|
|
|
|
// Validate token format
|
|
export function isValidToken(token: string): boolean {
|
|
// Check if token matches our format (word-word-word-4digits or word-word-4digits)
|
|
const longFormat = /^[a-z]+-[a-z]+-[a-z]+-\d{4}$/;
|
|
const shortFormat = /^[a-z]+-[a-z]+-\d{4}$/;
|
|
|
|
return longFormat.test(token) || shortFormat.test(token);
|
|
}
|