import { FakerError } from '../../errors/faker-error'; import type { Faker } from '../../faker'; import { toBase64Url } from '../../internal/base64'; import { ModuleBase } from '../../internal/module-base'; import { charMapping } from './char-mappings'; export type EmojiType = | 'smiley' | 'body' | 'person' | 'nature' | 'food' | 'travel' | 'activity' | 'object' | 'symbol' | 'flag'; export type HTTPStatusCodeType = | 'informational' | 'success' | 'clientError' | 'serverError' | 'redirection'; export type HTTPProtocolType = 'http' | 'https'; export enum IPv4Network { /** * Equivalent to: `0.0.0.0/0` */ Any = 'any', /** * Equivalent to: `127.0.0.0/8` * * @see [RFC1122](https://www.rfc-editor.org/rfc/rfc1122) */ Loopback = 'loopback', /** * Equivalent to: `10.0.0.0/8` * * @see [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) */ PrivateA = 'private-a', /** * Equivalent to: `172.16.0.0/12` * * @see [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) */ PrivateB = 'private-b', /** * Equivalent to: `192.168.0.0/16` * * @see [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) */ PrivateC = 'private-c', /** * Equivalent to: `192.0.2.0/24` * * @see [RFC5737](https://www.rfc-editor.org/rfc/rfc5737) */ TestNet1 = 'test-net-1', /** * Equivalent to: `198.51.100.0/24` * * @see [RFC5737](https://www.rfc-editor.org/rfc/rfc5737) */ TestNet2 = 'test-net-2', /** * Equivalent to: `203.0.113.0/24` * * @see [RFC5737](https://www.rfc-editor.org/rfc/rfc5737) */ TestNet3 = 'test-net-3', /** * Equivalent to: `169.254.0.0/16` * * @see [RFC3927](https://www.rfc-editor.org/rfc/rfc3927) */ LinkLocal = 'link-local', /** * Equivalent to: `224.0.0.0/4` * * @see [RFC5771](https://www.rfc-editor.org/rfc/rfc5771) */ Multicast = 'multicast', } export type IPv4NetworkType = `${IPv4Network}`; const ipv4Networks: Record = { [IPv4Network.Any]: '0.0.0.0/0', [IPv4Network.Loopback]: '127.0.0.0/8', [IPv4Network.PrivateA]: '10.0.0.0/8', [IPv4Network.PrivateB]: '172.16.0.0/12', [IPv4Network.PrivateC]: '192.168.0.0/16', [IPv4Network.TestNet1]: '192.0.2.0/24', [IPv4Network.TestNet2]: '198.51.100.0/24', [IPv4Network.TestNet3]: '203.0.113.0/24', [IPv4Network.LinkLocal]: '169.254.0.0/16', [IPv4Network.Multicast]: '224.0.0.0/4', }; /** * Checks whether the given string is a valid slug for `domainWord`s. * * @param slug The slug to check. */ function isValidDomainWordSlug(slug: string): boolean { return /^[a-z][a-z-]*[a-z]$/i.exec(slug) !== null; } /** * Tries various ways to produce a valid domain word slug, falling back to a random string if needed. * * @param faker The faker instance to use. * @param word The initial word to slugify. */ function makeValidDomainWordSlug(faker: Faker, word: string): string { const slug1 = faker.helpers.slugify(word); if (isValidDomainWordSlug(slug1)) { return slug1; } const slug2 = faker.helpers.slugify(faker.lorem.word()); if (isValidDomainWordSlug(slug2)) { return slug2; } return faker.string.alpha({ casing: 'lower', length: faker.number.int({ min: 4, max: 8 }), }); } /** * Module to generate internet related entries. * * ### Overview * * For user accounts, you may need an [`email()`](https://fakerjs.dev/api/internet.html#email) and a [`password()`](https://fakerjs.dev/api/internet.html#password), as well as a ASCII [`username()`](https://fakerjs.dev/api/internet.html#username) or Unicode [`displayName()`](https://fakerjs.dev/api/internet.html#displayname). Since the emails generated could coincidentally be real email addresses, you should not use these for sending real email addresses. If this is a concern, use [`exampleEmail()`](https://fakerjs.dev/api/internet.html#exampleemail) instead. * * For websites, you can generate a [`domainName()`](https://fakerjs.dev/api/internet.html#domainname) or a full [`url()`](https://fakerjs.dev/api/internet.html#url). * * To make your data more 🔥, you can use [`emoji()`](https://fakerjs.dev/api/internet.html#emoji). * * You also have access to a number of the more technical elements of web requests, such as [`httpMethod`](https://fakerjs.dev/api/internet.html#httpmethod), [`httpStatusCode`](https://fakerjs.dev/api/internet.html#httpstatuscode), [`ip`](https://fakerjs.dev/api/internet.html#ip), [`mac`](https://fakerjs.dev/api/internet.html#mac), [`userAgent`](https://fakerjs.dev/api/internet.html#useragent), and [`port`](https://fakerjs.dev/api/internet.html#port). */ export class InternetModule extends ModuleBase { /** * Generates an email address using the given person's name as base. * * @param options The options to use. * @param options.firstName The optional first name to use. If not specified, a random one will be chosen. * @param options.lastName The optional last name to use. If not specified, a random one will be chosen. * @param options.provider The mail provider domain to use. If not specified, a random free mail provider will be chosen. * @param options.allowSpecialCharacters Whether special characters such as ``.!#$%&'*+-/=?^_`{|}~`` should be included * in the email address. Defaults to `false`. * * @example * faker.internet.email() // 'Kassandra4@hotmail.com' * faker.internet.email({ firstName: 'Jeanne'}) // 'Jeanne63@yahoo.com' * faker.internet.email({ firstName: 'Jeanne'}) // 'Jeanne_Smith63@yahoo.com' * faker.internet.email({ firstName: 'Jeanne', lastName: 'Doe' }) // 'Jeanne.Doe63@yahoo.com' * faker.internet.email({ firstName: 'Jeanne', lastName: 'Doe', provider: 'example.fakerjs.dev' }) // 'Jeanne_Doe88@example.fakerjs.dev' * faker.internet.email({ firstName: 'Jeanne', lastName: 'Doe', provider: 'example.fakerjs.dev', allowSpecialCharacters: true }) // 'Jeanne%Doe88@example.fakerjs.dev' * * @since 2.0.1 */ email( options: { /** * The optional first name to use. * * @default faker.person.firstName() */ firstName?: string; /** * The optional last name to use. * * @default faker.person.lastName() */ lastName?: string; /** * The mail provider domain to use. If not specified, a random free mail provider will be chosen. */ provider?: string; /** * Whether special characters such as ``.!#$%&'*+-/=?^_`{|}~`` should be included in the email address. * * @default false */ allowSpecialCharacters?: boolean; } = {} ): string { const { firstName, lastName, provider = this.faker.helpers.arrayElement( this.faker.definitions.internet.free_email ), allowSpecialCharacters = false, } = options; let localPart: string = this.username({ firstName, lastName }); // Strip any special characters from the local part of the email address // This could happen if invalid chars are passed in manually in the firstName/lastName localPart = localPart.replaceAll(/[^A-Za-z0-9._+-]+/g, ''); // The local part of an email address is limited to 64 chars per RFC 3696 // We limit to 50 chars to be more realistic localPart = localPart.substring(0, 50); if (allowSpecialCharacters) { const usernameChars: string[] = [...'._-']; const specialChars: string[] = [...".!#$%&'*+-/=?^_`{|}~"]; localPart = localPart.replace( this.faker.helpers.arrayElement(usernameChars), this.faker.helpers.arrayElement(specialChars) ); } // local parts may not contain two or more consecutive . characters localPart = localPart.replaceAll(/\.{2,}/g, '.'); // local parts may not start with or end with a . character localPart = localPart.replace(/^\./, ''); localPart = localPart.replace(/\.$/, ''); return `${localPart}@${provider}`; } /** * Generates an email address using an example mail provider using the given person's name as base. * * @param options An options object. * @param options.firstName The optional first name to use. If not specified, a random one will be chosen. * @param options.lastName The optional last name to use. If not specified, a random one will be chosen. * @param options.allowSpecialCharacters Whether special characters such as ``.!#$%&'*+-/=?^_`{|}~`` should be included * in the email address. Defaults to `false`. * * @example * faker.internet.exampleEmail() // 'Helmer.Graham23@example.com' * faker.internet.exampleEmail({ firstName: 'Jeanne' }) // 'Jeanne96@example.net' * faker.internet.exampleEmail({ firstName: 'Jeanne' }) // 'Jeanne.Smith96@example.net' * faker.internet.exampleEmail({ firstName: 'Jeanne', lastName: 'Doe' }) // 'Jeanne_Doe96@example.net' * faker.internet.exampleEmail({ firstName: 'Jeanne', lastName: 'Doe', allowSpecialCharacters: true }) // 'Jeanne%Doe88@example.com' * * @since 3.1.0 */ exampleEmail( options: { /** * The optional first name to use. * * @default faker.person.firstName() */ firstName?: string; /** * The optional last name to use. * * @default faker.person.lastName() */ lastName?: string; /** * Whether special characters such as ``.!#$%&'*+-/=?^_`{|}~`` should be included in the email address. * * @default false */ allowSpecialCharacters?: boolean; } = {} ): string { const { firstName, lastName, allowSpecialCharacters = false } = options; const provider = this.faker.helpers.arrayElement( this.faker.definitions.internet.example_email ); return this.email({ firstName, lastName, provider, allowSpecialCharacters, }); } /** * Generates a username using the given person's name as base. * The resulting username may use neither, one or both of the names provided. * This will always return a plain ASCII string. * Some basic stripping of accents and transliteration of characters will be done. * * @param options An options object. * @param options.firstName The optional first name to use. If not specified, a random one will be chosen. * @param options.lastName The optional last name to use. If not specified, a random one will be chosen. * * @see faker.internet.displayName(): For generating an Unicode display name. * * @example * faker.internet.username() // 'Nettie_Zboncak40' * faker.internet.username({ firstName: 'Jeanne' }) // 'Jeanne98' * faker.internet.username({ firstName: 'Jeanne' }) // 'Jeanne.Smith98' * faker.internet.username({ firstName: 'Jeanne', lastName: 'Doe'}) // 'Jeanne_Doe98' * faker.internet.username({ firstName: 'John', lastName: 'Doe' }) // 'John.Doe' * faker.internet.username({ firstName: 'Hélene', lastName: 'Müller' }) // 'Helene_Muller11' * faker.internet.username({ firstName: 'Фёдор', lastName: 'Достоевский' }) // 'Fedor.Dostoevskii50' * faker.internet.username({ firstName: '大羽', lastName: '陳' }) // 'hlzp8d.tpv45' - note neither name is used * * @since 9.1.0 */ username( options: { /** * The optional first name to use. * * @default faker.person.firstName() */ firstName?: string; /** * The optional last name to use. * * @default faker.person.lastName() */ lastName?: string; } = {} ): string { const { firstName = this.faker.person.firstName(), lastName = this.faker.person.lastName(), lastName: hasLastName, } = options; const separator = this.faker.helpers.arrayElement(['.', '_']); const disambiguator = this.faker.number.int(99); const strategies: Array<() => string> = [ () => `${firstName}${separator}${lastName}${disambiguator}`, () => `${firstName}${separator}${lastName}`, ]; if (!hasLastName) { strategies.push(() => `${firstName}${disambiguator}`); } let result = this.faker.helpers.arrayElement(strategies)(); // There may still be non-ascii characters in the result. // First remove simple accents etc result = result .normalize('NFKD') //for example è decomposes to as e + ̀ .replaceAll(/[\u0300-\u036F]/g, ''); // removes combining marks result = [...result] .map((char) => { // If we have a mapping for this character, (for Cyrillic, Greek etc) use it if (charMapping[char]) { return charMapping[char]; } const charCode = char.codePointAt(0) ?? Number.NaN; if (charCode < 0x80) { // Keep ASCII characters return char; } // Final fallback return the Unicode char code value for Chinese, Japanese, Korean etc, base-36 encoded return charCode.toString(36); }) .join(''); result = result.replaceAll("'", ''); result = result.replaceAll(' ', ''); return result; } /** * Generates a display name using the given person's name as base. * The resulting display name may use one or both of the provided names. * If the input names include Unicode characters, the resulting display name will contain Unicode characters. * It will not contain spaces. * * @param options An options object. * @param options.firstName The optional first name to use. If not specified, a random one will be chosen. * @param options.lastName The optional last name to use. If not specified, a random one will be chosen. * * @see faker.internet.username(): For generating a plain ASCII username. * * @example * faker.internet.displayName() // 'Nettie_Zboncak40' * faker.internet.displayName({ firstName: 'Jeanne', lastName: 'Doe' }) // 'Jeanne98' - note surname not used. * faker.internet.displayName({ firstName: 'John', lastName: 'Doe' }) // 'John.Doe' * faker.internet.displayName({ firstName: 'Hélene', lastName: 'Müller' }) // 'Hélene_Müller11' * faker.internet.displayName({ firstName: 'Фёдор', lastName: 'Достоевский' }) // 'Фёдор.Достоевский50' * faker.internet.displayName({ firstName: '大羽', lastName: '陳' }) // '大羽.陳' * * @since 8.0.0 */ displayName( options: { /** * The optional first name to use. * * @default faker.person.firstName() */ firstName?: string; /** * The optional last name to use. * * @default faker.person.lastName() */ lastName?: string; } = {} ): string { const { firstName = this.faker.person.firstName(), lastName = this.faker.person.lastName(), } = options; const separator = this.faker.helpers.arrayElement(['.', '_']); const disambiguator = this.faker.number.int(99); const strategies: Array<() => string> = [ () => `${firstName}${disambiguator}`, () => `${firstName}${separator}${lastName}`, () => `${firstName}${separator}${lastName}${disambiguator}`, ]; let result = this.faker.helpers.arrayElement(strategies)(); result = result.replaceAll("'", ''); result = result.replaceAll(' ', ''); return result; } /** * Returns a random web protocol. Either `http` or `https`. * * @example * faker.internet.protocol() // 'http' * * @since 2.1.5 */ protocol(): 'http' | 'https' { const protocols: ['http', 'https'] = ['http', 'https']; return this.faker.helpers.arrayElement(protocols); } /** * Returns a random http method. * * Can be either of the following: * * - `GET` * - `POST` * - `PUT` * - `DELETE` * - `PATCH` * * @example * faker.internet.httpMethod() // 'PATCH' * * @since 5.4.0 */ httpMethod(): 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' { const httpMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] = [ 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', ]; return this.faker.helpers.arrayElement(httpMethods); } /** * Generates a random HTTP status code. * * @param options Options object. * @param options.types A list of the HTTP status code types that should be used. * * @example * faker.internet.httpStatusCode() // 200 * faker.internet.httpStatusCode({ types: ['success', 'serverError'] }) // 500 * * @since 7.0.0 */ httpStatusCode( options: { /** * A list of the HTTP status code types that should be used. * * @default Object.keys(faker.definitions.internet.http_status_code) */ types?: ReadonlyArray; } = {} ): number { const { types = Object.keys( this.faker.definitions.internet.http_status_code ) as HTTPStatusCodeType[], } = options; const httpStatusCodeType = this.faker.helpers.arrayElement(types); return this.faker.helpers.arrayElement( this.faker.definitions.internet.http_status_code[httpStatusCodeType] ); } /** * Generates a random http(s) url. * * @param options Optional options object. * @param options.appendSlash Whether to append a slash to the end of the url (path). Defaults to a random boolean value. * @param options.protocol The protocol to use. Defaults to `'https'`. * * @example * faker.internet.url() // 'https://remarkable-hackwork.info' * faker.internet.url({ appendSlash: true }) // 'https://slow-timer.info/' * faker.internet.url({ protocol: 'http', appendSlash: false }) // 'http://www.terrible-idea.com' * * @since 2.1.5 */ url( options: { /** * Whether to append a slash to the end of the url (path). * * @default faker.datatype.boolean() */ appendSlash?: boolean; /** * The protocol to use. * * @default 'https' */ protocol?: HTTPProtocolType; } = {} ): string { const { appendSlash = this.faker.datatype.boolean(), protocol = 'https' } = options; return `${protocol}://${this.domainName()}${appendSlash ? '/' : ''}`; } /** * Generates a random domain name. * * @example * faker.internet.domainName() // 'slow-timer.info' * * @since 2.0.1 */ domainName(): string { return `${this.domainWord()}.${this.domainSuffix()}`; } /** * Returns a random domain suffix. * * @example * faker.internet.domainSuffix() // 'com' * faker.internet.domainSuffix() // 'name' * * @since 2.0.1 */ domainSuffix(): string { return this.faker.helpers.arrayElement( this.faker.definitions.internet.domain_suffix ); } /** * Generates a random domain word. * * @example * faker.internet.domainWord() // 'close-reality' * faker.internet.domainWord() // 'weird-cytoplasm' * * @since 2.0.1 */ domainWord(): string { // Generate an ASCII "word" in the form `noun-adjective` // For locales with non-ASCII characters, we fall back to lorem words, or a random string const word1 = makeValidDomainWordSlug( this.faker, this.faker.word.adjective() ); const word2 = makeValidDomainWordSlug(this.faker, this.faker.word.noun()); return `${word1}-${word2}`.toLowerCase(); } /** * Generates a random IPv4 or IPv6 address. * * @example * faker.internet.ip() // '245.108.222.0' * faker.internet.ip() // '4e5:f9c5:4337:abfd:9caf:1135:41ad:d8d3' * * @since 2.0.1 */ ip(): string { return this.faker.datatype.boolean() ? this.ipv4() : this.ipv6(); } /** * Generates a random IPv4 address. * * @param options The optional options object. * @param options.cidrBlock The optional CIDR block to use. Must be in the format `x.x.x.x/y`. Defaults to `'0.0.0.0/0'`. * * @example * faker.internet.ipv4() // '245.108.222.0' * faker.internet.ipv4({ cidrBlock: '192.168.0.0/16' }) // '192.168.215.224' * * @since 6.1.1 */ ipv4(options?: { /** * The optional CIDR block to use. Must be in the format `x.x.x.x/y`. * * @default '0.0.0.0/0' */ cidrBlock?: string; }): string; /** * Generates a random IPv4 address. * * @param options The optional options object. * @param options.network The optional network to use. This is intended as an alias for well-known `cidrBlock`s. Defaults to `'any'`. * * @example * faker.internet.ipv4() // '245.108.222.0' * faker.internet.ipv4({ network: 'private-a' }) // '10.199.154.205' * * @since 6.1.1 */ ipv4(options?: { /** * The optional network to use. This is intended as an alias for well-known `cidrBlock`s. * * @default 'any' */ network?: IPv4NetworkType; }): string; /** * Generates a random IPv4 address. * * @param options The optional options object. * @param options.cidrBlock The optional CIDR block to use. Must be in the format `x.x.x.x/y`. Defaults to `'0.0.0.0/0'`. * @param options.network The optional network to use. This is intended as an alias for well-known `cidrBlock`s. Defaults to `'any'`. * * @example * faker.internet.ipv4() // '245.108.222.0' * faker.internet.ipv4({ cidrBlock: '192.168.0.0/16' }) // '192.168.215.224' * faker.internet.ipv4({ network: 'private-a' }) // '10.199.154.205' * * @since 6.1.1 */ ipv4( options?: | { /** * The optional CIDR block to use. Must be in the format `x.x.x.x/y`. * * @default '0.0.0.0/0' */ cidrBlock?: string; } | { /** * The optional network to use. This is intended as an alias for well-known `cidrBlock`s. * * @default 'any' */ network?: IPv4NetworkType; } ): string; ipv4( options: { cidrBlock?: string; network?: IPv4NetworkType } = {} ): string { const { network = 'any', cidrBlock = ipv4Networks[network] } = options; if (!/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/.test(cidrBlock)) { throw new FakerError( `Invalid CIDR block provided: ${cidrBlock}. Must be in the format x.x.x.x/y.` ); } const [ipText, subnet] = cidrBlock.split('/'); const subnetMask = 0xffffffff >>> Number.parseInt(subnet); const [rawIp1, rawIp2, rawIp3, rawIp4] = ipText.split('.').map(Number); const rawIp = (rawIp1 << 24) | (rawIp2 << 16) | (rawIp3 << 8) | rawIp4; const networkIp = rawIp & ~subnetMask; const hostOffset = this.faker.number.int(subnetMask); const ip = networkIp | hostOffset; return [ (ip >>> 24) & 0xff, (ip >>> 16) & 0xff, (ip >>> 8) & 0xff, ip & 0xff, ].join('.'); } /** * Generates a random IPv6 address. * * @example * faker.internet.ipv6() // '269f:1230:73e3:318d:842b:daab:326d:897b' * * @since 4.0.0 */ ipv6(): string { return Array.from({ length: 8 }, () => this.faker.string.hexadecimal({ length: 4, casing: 'lower', prefix: '', }) ).join(':'); } /** * Generates a random port number. * * @example * faker.internet.port() // 9414 * * @since 5.4.0 */ port(): number { return this.faker.number.int(65535); } /** * Generates a random user agent string. * * @example * faker.internet.userAgent() * // 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_1 like Mac OS X) AppleWebKit/537.19.86 (KHTML, like Gecko) Version/18_3 Mobile/15E148 Safari/598.43' * * @since 2.0.1 */ userAgent(): string { return this.faker.helpers.fake( this.faker.definitions.internet.user_agent_pattern ); } /** * Generates a random mac address. * * @param options An options object. * @param separator The optional separator to use. Can be either `':'`, `'-'` or `''`. Defaults to `':'`. * * @example * faker.internet.mac() // '32:8e:2e:09:c6:05' * * @since 3.0.0 */ mac(options?: { /** * The optional separator to use. Can be either `':'`, `'-'` or `''`. * * @default ':' */ separator?: string; }): string; /** * Generates a random mac address. * * @param separator The optional separator to use. Can be either `':'`, `'-'` or `''`. Defaults to `':'`. * * @example * faker.internet.mac() // '32:8e:2e:09:c6:05' * * @since 3.0.0 */ mac(separator?: string): string; /** * Generates a random mac address. * * @param options The optional separator or an options object. * @param separator The optional separator to use. Can be either `':'`, `'-'` or `''`. Defaults to `':'`. * * @example * faker.internet.mac() // '32:8e:2e:09:c6:05' * * @since 3.0.0 */ mac( options?: | string | { /** * The optional separator to use. Can be either `':'`, `'-'` or `''`. * * @default ':' */ separator?: string; } ): string; mac( options: | string | { /** * The optional separator to use. Can be either `':'`, `'-'` or `''`. * * @default ':' */ separator?: string; } = {} ): string { if (typeof options === 'string') { options = { separator: options }; } let { separator = ':' } = options; let i: number; let mac = ''; const acceptableSeparators = [':', '-', '']; if (!acceptableSeparators.includes(separator)) { separator = ':'; } for (i = 0; i < 12; i++) { mac += this.faker.number.hex(15); if (i % 2 === 1 && i !== 11) { mac += separator; } } return mac; } /** * Generates a random password-like string. Do not use this method for generating actual passwords for users. * Since the source of the randomness is not cryptographically secure, neither is this generator. * * @param options An options object. * @param options.length The length of the password to generate. Defaults to `15`. * @param options.memorable Whether the generated password should be memorable. Defaults to `false`. * @param options.pattern The pattern that all chars should match. * This option will be ignored, if `memorable` is `true`. Defaults to `/\w/`. * @param options.prefix The prefix to use. Defaults to `''`. * * @example * faker.internet.password() // '89G1wJuBLbGziIs' * faker.internet.password({ length: 20 }) // 'aF55c_8O9kZaPOrysFB_' * faker.internet.password({ length: 20, memorable: true }) // 'lawetimufozujosodedi' * faker.internet.password({ length: 20, memorable: true, pattern: /[A-Z]/ }) // 'HMAQDFFYLDDUTBKVNFVS' * faker.internet.password({ length: 20, memorable: true, pattern: /[A-Z]/, prefix: 'Hello ' }) // 'Hello IREOXTDWPERQSB' * * @since 2.0.1 */ password( options: { /** * The length of the password to generate. * * @default 15 */ length?: number; /** * Whether the generated password should be memorable. * * @default false */ memorable?: boolean; /** * The pattern that all chars should match. * This option will be ignored, if `memorable` is `true`. * * @default /\w/ */ pattern?: RegExp; /** * The prefix to use. * * @default '' */ prefix?: string; } = {} ): string { /* * password-generator ( function ) * Copyright(c) 2011-2013 Bermi Ferrer * MIT Licensed */ const vowel = /[aeiouAEIOU]$/; const consonant = /[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ]$/; const _password = ( length: number, memorable: boolean, pattern: RegExp, prefix: string ): string => { if (prefix.length >= length) { return prefix; } if (memorable) { pattern = consonant.test(prefix) ? vowel : consonant; } const n = this.faker.number.int(94) + 33; let char = String.fromCodePoint(n); if (memorable) { char = char.toLowerCase(); } if (!pattern.test(char)) { return _password(length, memorable, pattern, prefix); } return _password(length, memorable, pattern, prefix + char); }; const { length = 15, memorable = false, pattern = /\w/, prefix = '', } = options; return _password(length, memorable, pattern, prefix); } /** * Generates a random emoji. * * @param options Options object. * @param options.types A list of the emoji types that should be included. Possible values are `'smiley'`, `'body'`, `'person'`, `'nature'`, `'food'`, `'travel'`, `'activity'`, `'object'`, `'symbol'`, `'flag'`. By default, emojis from any type will be included. * * @example * faker.internet.emoji() // '🥰' * faker.internet.emoji({ types: ['food', 'nature'] }) // '🥐' * * @since 6.2.0 */ emoji( options: { /** * A list of the emoji types that should be used. * * @default Object.keys(faker.definitions.internet.emoji) */ types?: ReadonlyArray; } = {} ): string { const { types = Object.keys(this.faker.definitions.internet.emoji) as EmojiType[], } = options; const emojiType = this.faker.helpers.arrayElement(types); return this.faker.helpers.arrayElement( this.faker.definitions.internet.emoji[emojiType] ); } /** * Generates a random JWT (JSON Web Token) Algorithm. * * @see faker.internet.jwt(): For generating random JWT (JSON Web Token). * * @example * faker.internet.jwtAlgorithm() // 'HS256' * faker.internet.jwtAlgorithm() // 'RS512' * * @since 9.1.0 */ jwtAlgorithm(): string { return this.faker.helpers.arrayElement( this.faker.definitions.internet.jwt_algorithm ); } /** * Generates a random JWT (JSON Web Token). * * Please note that this method generates a random signature instead of a valid one. * * @param options The optional options object. * @param options.header The Header to use for the token. Defaults to a random object with the following fields: `alg` and `typ`. * @param options.payload The Payload to use for the token. Defaults to a random object with the following fields: `iat`, `exp`, `nbf`, `iss`, `sub`, `aud`, and `jti`. * @param options.refDate The date to use as reference point for the newly generated date. * * @see https://datatracker.ietf.org/doc/html/rfc7519 * @see faker.internet.jwtAlgorithm(): For generating random JWT (JSON Web Token) Algorithm. * * @example * faker.internet.jwt() // 'eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MzI2MzgxMDYsImV4cCI6MTczMjY5MjUwOSwibmJmIjoxNzA1MDgxNjQ4LCJpc3MiOiJHdXRrb3dza2kgYW5kIFNvbnMiLCJzdWIiOiJlMzQxZjMwNS0yM2I2LTRkYmQtOTY2ZC1iNDRiZmM0ZGIzMGUiLCJhdWQiOiI0YzMwZGE3Yi0zZDUzLTQ4OGUtYTAyZC0zOWI2MDZiZmYxMTciLCJqdGkiOiJiMGZmOTMzOC04ODMwLTRmNDgtYjA3Ny1kNDNmMjU2OGZlYzAifQ.oDLVR73M0u5SjMPlc1aruxbdK7l2titXSeo9J5M1JUd65a1X9MhCz7FOobtX8eaj' * faker.internet.jwt({ header: { alg: 'HS256' }}) // 'eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MTg2MTM3MTIsImV4cCI6MTcxODYzMzY3OSwibmJmIjoxNjk3MjYzNjMwLCJpc3MiOiJEb3lsZSBhbmQgU29ucyIsInN1YiI6IjYxYWRkYWFmLWY4MjktNDkzZS1iNTI1LTJjMGJkNjkzOTdjNyIsImF1ZCI6IjczNjcyMjVjLWIwMWMtNGE1My1hYzQyLTYwOWJkZmI1MzBiOCIsImp0aSI6IjU2Y2ZkZjAxLWRhMzMtNGUxNi04MzJiLTFlYTk3ZGY1MTQ2YSJ9.5iUgaCaFVPZ8d1QD0xMjoeJbmPVyUfKfoRQ6Njzm5MLp5F4UMh5REbPCrW70fAkr' * faker.internet.jwt({ payload: { iss: 'Acme' }}) // 'eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJBY21lIn0.syUt0GBukNac8Cn1AGKFq2SWAXWy1YIfl0uOYiwg6TZ3omAW0c7FGWY6bC7ZOFSt' * faker.internet.jwt({ refDate: '2020-01-01T00:00:00.000Z' }) // 'eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1Nzc4MDY4NDUsImV4cCI6MTU3Nzg0NjI4MCwibmJmIjoxNTgxNTQyMDYwLCJpc3MiOiJLcmVpZ2VyLCBBbHRlbndlcnRoIGFuZCBQYXVjZWsiLCJzdWIiOiI5NzVjMjMyOS02MDlhLTRjYTYtYjBkZi05ZmY4MGZiNDUwN2QiLCJhdWQiOiI0ODQxZWYwNi01OWYwLTQzMWEtYmFmZi0xMjkxZmRhZDdhNjgiLCJqdGkiOiJmNDBjZTJiYi00ZWYyLTQ1MjMtOGIxMy1kN2Q4NTA5N2M2ZTUifQ.cuClEZQ0CyPIMVS5uxrMwWXz0wcqFFdt0oNne3PMryyly0jghkxVurss2TapMC3C' * * @since 9.1.0 */ jwt( options: { /** * The header to use for the token. If present, it will replace any default values. * * @default * { * alg: faker.internet.jwtAlgorithm(), * typ: 'JWT' * } */ header?: Record; /** * The payload to use for the token. If present, it will replace any default values. * * @default * { * iat: faker.date.recent(), * exp: faker.date.soon(), * nbf: faker.date.anytime(), * iss: faker.company.name(), * sub: faker.string.uuid(), * aud: faker.string.uuid(), * jti: faker.string.uuid() * } */ payload?: Record; /** * The date to use as reference point for the newly generated date. * * @default faker.defaultRefDate() */ refDate?: string | Date | number; } = {} ): string { const { refDate = this.faker.defaultRefDate() } = options; const iatDefault = this.faker.date.recent({ refDate }); const { header = { alg: this.jwtAlgorithm(), typ: 'JWT', }, payload = { iat: Math.round(iatDefault.valueOf() / 1000), exp: Math.round( this.faker.date.soon({ refDate: iatDefault }).valueOf() / 1000 ), nbf: Math.round(this.faker.date.anytime({ refDate }).valueOf() / 1000), iss: this.faker.company.name(), sub: this.faker.string.uuid(), aud: this.faker.string.uuid(), jti: this.faker.string.uuid(), }, } = options; const encodedHeader = toBase64Url(JSON.stringify(header)); const encodedPayload = toBase64Url(JSON.stringify(payload)); const signature = this.faker.string.alphanumeric(64); return `${encodedHeader}.${encodedPayload}.${signature}`; } }