{"version":3,"file":"assets/main.efcc24d34845c6d049ce.js","mappings":"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","sources":["webpack://sm-locksmith-iframe/./events.ts","webpack://sm-locksmith-iframe/./src/machine.ts","webpack://sm-locksmith-iframe/./src/locksmith.ts","webpack://sm-locksmith-iframe/./index.ts","webpack://sm-locksmith-iframe/./utils/index.ts"],"sourcesContent":["export enum IframeEvents {\n createKeys = 'CREATE_ASYMMETRIC_KEYS',\n requestPublicKey = 'REQUEST_PUBLIC_KEY',\n recoverMasterKey = 'IMPORT_SAVED_MASTER_KEY',\n decodeFileFromUrl = 'DECODE_FILE_FROM_URL',\n}\n\nexport enum ParentEvents {\n identify = 'IDENTIFY',\n requestSecrets = 'REQUEST_SECRETS',\n decodeFileFromUrl = 'DECODE_FILE_FROM_URL',\n}\n\nexport enum WorkerEvents {\n keysCreated = 'RSA_KEYS_CREATED',\n keysCreationFailed = 'RSA_KEYS_CREATION_FAILED',\n\n masterKeyDecrypted = 'MASTER_KEY_DECRYPTED',\n masterKeyDecryptFailed = 'MASTER_KEY_DECRYPT_FAILED',\n\n masterKeyImported = 'MASTER_KEY_IMPORTED',\n masterKeyImportFailed = 'MASTER_KEY_IMPORT_FAILED',\n\n fileDecoded = 'FILE_DECODED',\n fileDecodeFailed = 'FILE_DECODE_FAILED',\n}\n","import { createMachine, assign, EventObject } from '@xstate/fsm';\n\nexport interface Context {\n retries: number;\n userId: string | null;\n session: string | null;\n keyUrl: string;\n}\n\nexport enum State {\n idle = 'idle',\n recoverKey = 'recoverKey',\n createRSAKeys = 'createRSAKeys',\n requestMasterKey = 'requestMasterKey',\n success = 'success',\n failure = 'failure',\n}\n\nexport enum Event {\n userIdReceived = 'USER_ID_RECEIVED',\n\n keyRecovered = 'KEY_RECOVERED',\n keyNotFound = 'KEY_NOT_FOUND',\n keyRecoverError = 'KEY_RECOVER_ERROR',\n keyInvalid = 'KEY_INVALID',\n\n rsaKeyCreated = 'RSA_KEY_CREATED',\n rsaKeyCreationFailed = 'RSA_KEY_CREATION_FAILED',\n\n keyImported = 'KEY_IMPORTED',\n keyImportFailed = 'KEY_IMPORT_FAILED',\n\n retry = 'RETRY',\n}\n\ninterface UserIdReceivedEvent extends EventObject {\n userId: string;\n}\n\ninterface KeyRecoveredEvent extends EventObject {\n session: string;\n}\n\nexport type SupportedEvents = EventObject | UserIdReceivedEvent | KeyRecoveredEvent;\n\nexport default createMachine({\n id: '__locksmith',\n initial: 'idle',\n context: {\n retries: 0,\n userId: null,\n session: null,\n keyUrl: 'SHIHO',\n },\n\n states: {\n [State.idle]: {\n on: {\n [Event.userIdReceived]: {\n target: State.recoverKey,\n actions: assign({\n userId: (_context, event) => {\n const e = event as UserIdReceivedEvent;\n return e.userId;\n },\n }),\n },\n },\n },\n [State.recoverKey]: {\n on: {\n [Event.keyRecovered]: {\n target: State.success,\n actions: assign({\n session: (_context, event) => {\n const e = event as KeyRecoveredEvent;\n return e.session;\n },\n }),\n },\n [Event.keyNotFound]: State.createRSAKeys,\n [Event.keyRecoverError]: State.failure,\n [Event.keyInvalid]: State.failure,\n },\n },\n createRSAKeys: {\n on: {\n [Event.rsaKeyCreated]: State.requestMasterKey,\n [Event.rsaKeyCreationFailed]: State.failure,\n },\n },\n requestMasterKey: {\n on: {\n [Event.keyImported]: {\n target: State.success,\n actions: assign({\n session: (_context, event) => {\n const e = event as KeyRecoveredEvent;\n return e.session;\n },\n }),\n },\n [Event.keyImportFailed]: State.failure,\n },\n },\n success: {},\n failure: {\n on: {\n [Event.retry]: {\n target: State.createRSAKeys,\n actions: assign({\n retries: context => context.retries + 1,\n }),\n },\n },\n },\n },\n});\n","import { wrapValue, unwrapValue } from '../utils';\nimport { IframeEvents, ParentEvents } from '../events';\nimport { interpret, StateMachine } from '@xstate/fsm';\nimport { captureException } from '@sentry/browser';\nimport machine, { Event as MachineEvent, State, Context, SupportedEvents } from './machine';\nimport {\n ParentHandshake,\n WorkerMessenger,\n ChildHandshake,\n WindowMessenger,\n RemoteHandle,\n} from 'post-me';\nimport { methods } from './worker';\n\nconst worker = new Worker(new URL('./worker', import.meta.url));\n\n// Not implemented in Firefox yet\n// https://developer.mozilla.org/en-US/docs/Web/API/Location/ancestorOrigins\nconst remoteOrigin =\n 'ancestorOrigins' in document.location\n ? document.location.ancestorOrigins[0]\n : new URL(document.referrer).origin;\n\nconst workerMessenger = new WorkerMessenger({ worker });\nconst parentMessenger = new WindowMessenger({\n localWindow: window,\n remoteWindow: window.parent,\n remoteOrigin,\n});\n\nconst LS_ENTRY = 'k';\n\nconst service = interpret(machine);\n\nexport default class Locksmith {\n parentHandle!: RemoteHandle;\n workerHandle!: RemoteHandle;\n\n constructor() {\n // Handling slow cases when the Worker\n // could take up to 60' (arbitrary) to be ready\n const handshakeRetries = 300;\n const handshakeRetryInterval = 200;\n\n service.subscribe(this.handleStateChange);\n service.start();\n\n ParentHandshake(workerMessenger, {}, handshakeRetries, handshakeRetryInterval)\n .then(workerConnection => {\n this.workerHandle = workerConnection.remoteHandle();\n\n ChildHandshake(parentMessenger, {\n [ParentEvents.identify]: (userId: string) => this.identifyUser(userId),\n [ParentEvents.requestSecrets]: (userId: string) => this.requestSecretsForUser(userId),\n [ParentEvents.decodeFileFromUrl]: (url: string) => this.decodeFileFromUrl(url),\n }).then(parentConnection => {\n this.parentHandle = parentConnection.remoteHandle();\n });\n })\n .catch(e => captureException(e));\n }\n\n identifyUser(userId: string) {\n service.send({\n type: MachineEvent.userIdReceived,\n userId,\n });\n\n return new Promise(resolve => {\n const listener = service.subscribe(state => {\n if (state.value !== State.success) {\n return;\n }\n\n listener.unsubscribe();\n resolve(state.context.session);\n });\n });\n }\n\n async requestSecretsForUser(userId: string) {\n await this.identifyUser(userId);\n return this.recoverKey(userId);\n }\n\n retry(retries: number) {\n localStorage.removeItem(LS_ENTRY);\n\n if (retries > 1) {\n service.stop();\n return;\n }\n\n service.send(MachineEvent.retry);\n }\n\n handleStateChange = (\n state: StateMachine.State<\n Context,\n SupportedEvents,\n {\n value: State;\n context: Context;\n }\n >\n ) => {\n switch (state.value) {\n case State.failure:\n this.retry(service.state.context.retries);\n break;\n\n case State.createRSAKeys:\n this.workerHandle\n .call(IframeEvents.createKeys)\n .then(() => {\n this.checkForChanges();\n service.send(MachineEvent.rsaKeyCreated);\n })\n .catch(() => {\n service.send(MachineEvent.rsaKeyCreationFailed);\n });\n break;\n\n case State.requestMasterKey: {\n this.workerHandle\n .call(IframeEvents.requestPublicKey, this.getKeyUrl())\n .then(({ session, expires, key }) => {\n this.checkForChanges();\n this.handleStore(session, expires, key);\n service.send({\n type: MachineEvent.keyImported,\n session,\n });\n })\n .catch(() => {\n service.send(MachineEvent.keyImportFailed);\n });\n break;\n }\n\n case State.recoverKey: {\n if (!state.context.userId) {\n throw new Error('User is not authenticated');\n }\n\n const userId = state.context.userId;\n this.recoverKey(userId)\n .then(data => {\n if (!data) {\n service.send(MachineEvent.keyNotFound);\n } else {\n this.workerHandle\n .call(IframeEvents.recoverMasterKey, data.key)\n .then(() => {\n service.send({\n type: MachineEvent.keyRecovered,\n session: data.session,\n });\n })\n .catch(() => {\n service.send(MachineEvent.keyRecoverError);\n });\n }\n })\n .catch(() => service.send(MachineEvent.keyInvalid));\n break;\n }\n\n case State.idle:\n default:\n break;\n }\n };\n\n checkForChanges() {\n if (localStorage.getItem(LS_ENTRY)) {\n throw new Error('Storage Change Detected');\n }\n }\n\n handleStore(session: string, expiration: Date, masterKey: string) {\n const userId = service.state.context.userId;\n\n if (!userId) {\n throw new Error('User is not authenticated');\n }\n\n localStorage.setItem(LS_ENTRY, wrapValue(userId, session, expiration, masterKey));\n }\n\n recoverKey(userId: string): Promise {\n return new Promise(function (resolve, reject) {\n const storedData = localStorage.getItem(LS_ENTRY);\n\n if (!storedData) {\n return resolve(undefined);\n }\n\n try {\n const [id, session, date, key] = unwrapValue(storedData);\n\n if (id !== userId) {\n throw new Error('UserId mismatch');\n }\n\n if (new Date(date).getTime() <= Date.now()) {\n throw new Error('Key expired');\n }\n\n return resolve({\n key,\n session,\n });\n } catch (e) {\n return reject();\n }\n });\n }\n\n decodeFileFromUrl(url: string) {\n if (!service.state.context.session) {\n throw new Error('User is not authenticated');\n }\n\n return this.workerHandle.call(\n IframeEvents.decodeFileFromUrl,\n url,\n service.state.context.session\n );\n }\n\n getKeyUrl() {\n return document && document.location.hostname.includes('makemusic')\n ? KEY_EXCHANGE_URL_MM\n : KEY_EXCHANGE_URL;\n }\n}\n","import { init } from '@sentry/browser';\nimport { Dedupe, ExtraErrorData } from '@sentry/integrations';\nimport Locksmith from './src/locksmith';\n\ninit({\n dsn: SM_SENTRY_DSN,\n integrations: [new Dedupe(), new ExtraErrorData()],\n autoSessionTracking: false,\n environment: SM_SENTRY_ENV,\n release: APP_VERSION,\n ignoreErrors: [\n // see https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded\n 'ResizeObserver loop limit exceeded',\n ],\n});\n\nnew Locksmith();\n","// http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html\n\nexport function utf8ToB64(str: string): string {\n return btoa(unescape(encodeURIComponent(str)));\n}\n\nexport function b64ToUtf8(str: string): string {\n return decodeURIComponent(escape(atob(str)));\n}\n\nexport function wrapValue(userId: string, session: string, date: Date, key: string) {\n const random = Math.max(1, Math.round(Math.random() * 9));\n const salt = Math.random().toString(36).substr(2, random);\n const obj = JSON.stringify([userId, session, date.toJSON(), key]);\n return `${salt}${utf8ToB64(obj)}${random}`;\n}\n\nexport function unwrapValue(value: string) {\n const random = value.slice(-1);\n const data = b64ToUtf8(value.slice(parseInt(random), -1));\n const obj = JSON.parse(data);\n return obj;\n}\n"],"names":["IframeEvents","ParentEvents","State","Event","createMachine","id","initial","context","retries","userId","session","keyUrl","states","idle","on","userIdReceived","target","recoverKey","actions","assign","_context","event","keyRecovered","success","keyNotFound","createRSAKeys","keyRecoverError","failure","keyInvalid","rsaKeyCreated","requestMasterKey","rsaKeyCreationFailed","keyImported","keyImportFailed","retry","worker","Worker","URL","remoteOrigin","document","location","ancestorOrigins","referrer","origin","workerMessenger","WorkerMessenger","parentMessenger","WindowMessenger","localWindow","window","remoteWindow","parent","LS_ENTRY","service","interpret","machine","init","dsn","SM_SENTRY_DSN","integrations","Dedupe","ExtraErrorData","autoSessionTracking","environment","SM_SENTRY_ENV","release","APP_VERSION","ignoreErrors","constructor","state","value","this","workerHandle","call","createKeys","then","checkForChanges","send","MachineEvent","catch","requestPublicKey","getKeyUrl","_ref","expires","key","handleStore","type","Error","data","recoverMasterKey","subscribe","handleStateChange","start","ParentHandshake","workerConnection","remoteHandle","ChildHandshake","identify","identifyUser","requestSecrets","requestSecretsForUser","decodeFileFromUrl","url","parentConnection","parentHandle","e","captureException","Promise","resolve","listener","unsubscribe","localStorage","removeItem","stop","getItem","expiration","masterKey","setItem","date","random","Math","max","round","toString","substr","str","JSON","stringify","toJSON","btoa","unescape","encodeURIComponent","wrapValue","reject","storedData","undefined","slice","parseInt","decodeURIComponent","escape","atob","parse","unwrapValue","Date","getTime","now","hostname","includes","KEY_EXCHANGE_URL_MM","KEY_EXCHANGE_URL"],"sourceRoot":""}