{"version":3,"sources":["../../src/utilities/authProviders.ts","../../src/utilities/hash.ts","../../src/utilities/json.ts","../../src/utilities/media.ts","../../src/utilities/random.ts","../../src/utilities/retry.ts"],"sourcesContent":["import axios from 'axios'\nimport jwt from 'jsonwebtoken'\nimport jwksClient from 'jwks-rsa'\n\nimport { EquippedError } from '../errors'\n\nexport const signinWithGoogle = async (idToken: string) => {\n\tconst authUrl = `https://oauth2.googleapis.com/tokeninfo?id_token=${idToken}`\n\tconst { data } = await axios.get(authUrl).catch((err) => {\n\t\tthrow new EquippedError('Failed to sign in with google', { idToken }, err)\n\t})\n\tdata.first_name = data.given_name\n\tdata.last_name = data.family_name\n\treturn data as {\n\t\temail: string\n\t\temail_verified: 'true' | 'false'\n\t\tfirst_name: string\n\t\tlast_name: string\n\t\tpicture: string\n\t\tsub: string\n\t} & Record<string, any>\n}\n\nexport const signinWithApple = async (idToken: string) => {\n\ttry {\n\t\tconst APPLE_BASE = 'https://appleid.apple.com'\n\t\tconst json = jwt.decode(idToken, { complete: true })\n\t\tif (!json?.header) throw new EquippedError('Missing JWT header', { idToken, json })\n\t\tconst { kid, alg } = json.header\n\t\tconst publicKey = await jwksClient({ jwksUri: `${APPLE_BASE}/auth/keys`, cache: true })\n\t\t\t.getSigningKey(kid)\n\t\t\t.then((key) => key.getPublicKey())\n\t\t\t.catch(() => null)\n\t\tif (!publicKey) throw new EquippedError('no publicKey', { idToken, publicKey, json })\n\t\tconst data = jwt.verify(idToken, publicKey, { algorithms: [alg as any] }) as Record<string, any>\n\t\tif (!data) throw new EquippedError('no data', { idToken, data })\n\t\tif (data.iss !== APPLE_BASE) throw new EquippedError('iss doesnt match', { idToken, data })\n\t\tif (data.exp * 1000 < Date.now()) throw new EquippedError('expired idToken', { idToken, data })\n\t\t// TODO: Find out how to get profile data from api\n\t\treturn data as {\n\t\t\temail?: string\n\t\t\tsub: string\n\t\t\temail_verified?: 'true' | 'false'\n\t\t\tis_private_email?: 'true' | 'false'\n\t\t} & Record<string, any>\n\t} catch (err) {\n\t\tthrow new EquippedError('Failed to sign in with apple', { idToken }, err)\n\t}\n}\n\nexport const signinWithFacebook = async (accessToken: string, fields = [] as string[]) => {\n\tfields = [...new Set([...fields, 'name', 'picture', 'email'])]\n\tconst { data } = await axios\n\t\t.request({\n\t\t\tmethod: 'get',\n\t\t\turl: 'https://graph.facebook.com/v15.0/me',\n\t\t\tparams: {\n\t\t\t\tfields: fields.join(','),\n\t\t\t\taccess_token: accessToken,\n\t\t\t},\n\t\t})\n\t\t.catch((err) => {\n\t\t\tthrow new EquippedError('Failed to sign in with facebook', { accessToken, fields }, err)\n\t\t})\n\tconst isValidData = fields.every((key) => key in data)\n\tif (!isValidData) throw new EquippedError('Incomplete scope for access token', { accessToken, fields, data })\n\tdata.email_verified = 'true'\n\treturn data as {\n\t\tid: string\n\t\temail: string\n\t\temail_verified: 'true' | 'false'\n\t\tname: string\n\t\tpicture: {\n\t\t\tdata: { height: number; is_silhouette: boolean; url: string; width: number }\n\t\t}\n\t} & Record<string, any>\n}\n","import * as bcrypt from 'bcryptjs'\n\nimport { Instance } from '../instance'\n\nexport const hash = async (password: string) => {\n\tpassword = password.trim()\n\tif (!password) return ''\n\treturn await bcrypt.hash(password, Instance.get().settings.utils.hashSaltRounds)\n}\n\nexport const compare = async (plainPassword: string, hashed: string) => {\n\tplainPassword = plainPassword.trim()\n\tif (!plainPassword && plainPassword === hashed) return true\n\treturn await bcrypt.compare(plainPassword, hashed)\n}\n","export const parseJSONValue = (data: any) => {\n\ttry {\n\t\tif (data?.constructor?.name !== 'String') return data\n\t\treturn JSON.parse(data)\n\t} catch {\n\t\treturn data\n\t}\n}\n","import { parseBuffer } from 'music-metadata'\n\nexport const getMediaDuration = async (buffer: Buffer) => {\n\ttry {\n\t\tconst meta = await parseBuffer(buffer)\n\t\treturn meta.format.duration ?? 0\n\t} catch {\n\t\treturn 0\n\t}\n}\n","import crypto from 'crypto'\n\nexport function string(length = 20) {\n\treturn crypto.randomBytes(length).toString('hex').slice(0, length)\n}\n\nexport function number(min = 0, max = 2 ** 48 - 1) {\n\treturn crypto.randomInt(min, max)\n}\n","import { EquippedError } from '../errors'\n\nexport const sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms))\n\nexport const retry = async <T>(cb: () => Promise<{ done: true; value: T } | { done: false }>, tries: number, waitTimeInMs: number) => {\n\tif (tries <= 0) throw new EquippedError('out of tries', { tries, waitTimeInMs })\n\tconst result = await cb()\n\tif (result.done === true) return result.value\n\tawait sleep(waitTimeInMs)\n\treturn await retry(cb, tries - 1, waitTimeInMs)\n}\n"],"mappings":"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","names":["authProviders_exports","__export","signinWithApple","signinWithFacebook","signinWithGoogle","axios","jwt","jwksClient","signinWithGoogle","idToken","authUrl","data","axios","err","EquippedError","signinWithApple","APPLE_BASE","json","jwt","kid","alg","publicKey","jwksClient","key","signinWithFacebook","accessToken","fields","hash_exports","__export","compare","hash","bcrypt","hash","password","Instance","compare","plainPassword","hashed","parseJSONValue","data","parseBuffer","getMediaDuration","buffer","random_exports","__export","number","string","crypto","length","min","max","sleep","ms","resolve","retry","cb","tries","waitTimeInMs","EquippedError","result"]}