UNPKG

@upbond/customauth

Version:

CustomAuth login with torus to get user private key

95 lines (83 loc) 4.1 kB
import { getPublic, sign } from "@toruslabs/eccrypto"; import { get, post } from "@toruslabs/http-helpers"; import { decryptData, encryptData, keccak256 } from "@toruslabs/metadata-helpers"; import { LoginDetails } from "../handlers/interfaces"; import { REDIRECT_PARAMS_STORAGE_METHOD, REDIRECT_PARAMS_STORAGE_METHOD_TYPE } from "./enums"; import { are3PCSupported, storageAvailable } from "./helpers"; import log from "./loglevel"; class StorageHelper { private currentStorageMethod: REDIRECT_PARAMS_STORAGE_METHOD_TYPE = REDIRECT_PARAMS_STORAGE_METHOD.LOCAL_STORAGE; private isInitialized = false; private storageServerUrl = "https://broadcast-server.tor.us"; constructor(serverUrl: string) { this.storageServerUrl = serverUrl; } init() { const support = are3PCSupported(); const localStorageAvailable = storageAvailable(REDIRECT_PARAMS_STORAGE_METHOD.LOCAL_STORAGE); if (support && localStorageAvailable) { // use local storage as default for storing stuff this.currentStorageMethod = REDIRECT_PARAMS_STORAGE_METHOD.LOCAL_STORAGE; } else { // use server store as default for storing stuff this.currentStorageMethod = REDIRECT_PARAMS_STORAGE_METHOD.SERVER; } this.isInitialized = true; } async storeLoginDetails(params: LoginDetails, scope: string): Promise<void> { if (!this.isInitialized) throw new Error("StorageHelper is not initialized"); if (this.currentStorageMethod === REDIRECT_PARAMS_STORAGE_METHOD.SERVER) { const privKey = keccak256(Buffer.from(scope, "utf8")); const privKeyHex = privKey.toString("hex"); const publicKeyHex = getPublic(privKey).toString("hex"); const encData = await encryptData(privKeyHex, params); const signature = (await sign(privKey, keccak256(Buffer.from(encData, "utf8")))).toString("hex"); await post(`${this.storageServerUrl}/store/set`, { key: publicKeyHex, data: encData, signature }); } else { window.localStorage.setItem(`torus_login_${scope}`, JSON.stringify(params)); } } async retrieveLoginDetails(scope: string): Promise<LoginDetails> { if (!this.isInitialized) throw new Error("StorageHelper is not initialized"); if (this.currentStorageMethod === REDIRECT_PARAMS_STORAGE_METHOD.SERVER) { const privKey = keccak256(Buffer.from(scope, "utf8")); const privKeyHex = privKey.toString("hex"); const publicKeyHex = getPublic(privKey).toString("hex"); try { const encData: { message: string; success: boolean } = await get(`${this.storageServerUrl}/store/get?key=${publicKeyHex}`); if (encData.message) { const loginDetails = await decryptData<LoginDetails>(privKeyHex, encData.message); return loginDetails; } } catch (error) { if ((error as Response).status === 404) { log.warn(error, "Session likely expired"); } else { throw error; } } } const loginDetails = window.localStorage.getItem(`torus_login_${scope}`); return JSON.parse(loginDetails || "{}") as LoginDetails; } clearLoginDetailsStorage(scope: string): void { if (!this.isInitialized) throw new Error("StorageHelper is not initialized"); if (this.currentStorageMethod === REDIRECT_PARAMS_STORAGE_METHOD.LOCAL_STORAGE) { window.localStorage.removeItem(`torus_login_${scope}`); } // No need to clear server details cause they auto expire and scope is never re-used for different login attempts } clearOrphanedLoginDetails(): void { if (!this.isInitialized) throw new Error("StorageHelper is not initialized"); if (this.currentStorageMethod === REDIRECT_PARAMS_STORAGE_METHOD.LOCAL_STORAGE) { const allStorageKeys = Object.keys(window.localStorage); allStorageKeys.forEach((key) => { if (key.startsWith("torus_login_")) { window.localStorage.removeItem(key); } }); } // No need to clear server details cause they auto expire and scope is never re-used for different login attempts } } export default StorageHelper;