summaryrefslogtreecommitdiff
path: root/web/js/browser/lib/client.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/js/browser/lib/client.js')
-rw-r--r--web/js/browser/lib/client.js792
1 files changed, 792 insertions, 0 deletions
diff --git a/web/js/browser/lib/client.js b/web/js/browser/lib/client.js
new file mode 100644
index 0000000..fadbdd9
--- /dev/null
+++ b/web/js/browser/lib/client.js
@@ -0,0 +1,792 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __rest = (this && this.__rest) || function (s, e) {
+ var t = {};
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
+ t[p] = s[p];
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
+ t[p[i]] = s[p[i]];
+ }
+ return t;
+};
+import * as crypto from './crypto';
+import * as hawk from './hawk';
+var ERRORS;
+(function (ERRORS) {
+ ERRORS[ERRORS["INVALID_TIMESTAMP"] = 111] = "INVALID_TIMESTAMP";
+ ERRORS[ERRORS["INCORRECT_EMAIL_CASE"] = 120] = "INCORRECT_EMAIL_CASE";
+})(ERRORS || (ERRORS = {}));
+var tokenType;
+(function (tokenType) {
+ tokenType["sessionToken"] = "sessionToken";
+ tokenType["passwordForgotToken"] = "passwordForgotToken";
+ tokenType["keyFetchToken"] = "keyFetchToken";
+ tokenType["accountResetToken"] = "accountResetToken";
+ tokenType["passwordChangeToken"] = "passwordChangeToken";
+})(tokenType || (tokenType = {}));
+var AUTH_PROVIDER;
+(function (AUTH_PROVIDER) {
+ AUTH_PROVIDER["GOOGLE"] = "google";
+ AUTH_PROVIDER["APPLE"] = "apple";
+})(AUTH_PROVIDER || (AUTH_PROVIDER = {}));
+function langHeader(lang) {
+ return new Headers(lang
+ ? {
+ 'Accept-Language': lang,
+ }
+ : {});
+}
+function pathWithKeys(path, keys) {
+ return `${path}${keys ? '?keys=true' : ''}`;
+}
+function fetchOrTimeout(input, init = {}, timeout) {
+ return __awaiter(this, void 0, void 0, function* () {
+ let id = 0;
+ if (typeof AbortController !== 'undefined') {
+ const aborter = new AbortController();
+ init.signal = aborter.signal;
+ id = setTimeout((() => aborter.abort()), timeout);
+ }
+ try {
+ return yield fetch(input, init);
+ }
+ finally {
+ if (id) {
+ clearTimeout(id);
+ }
+ }
+ });
+}
+function cleanStringify(value) {
+ // remove keys with null values
+ return JSON.stringify(value, (_, v) => (v == null ? undefined : v));
+}
+export default class AuthClient {
+ constructor(authServerUri, options = {}) {
+ if (new RegExp(`/${AuthClient.VERSION}$`).test(authServerUri)) {
+ this.uri = authServerUri;
+ }
+ else {
+ this.uri = `${authServerUri}/${AuthClient.VERSION}`;
+ }
+ this.localtimeOffsetMsec = 0;
+ this.timeout = options.timeout || 30000;
+ }
+ static create(authServerUri) {
+ return __awaiter(this, void 0, void 0, function* () {
+ if (typeof TextEncoder === 'undefined') {
+ yield import(
+ // @ts-ignore
+ /* webpackChunkName: "fast-text-encoding" */ 'fast-text-encoding');
+ }
+ yield crypto.checkWebCrypto();
+ return new AuthClient(authServerUri);
+ });
+ }
+ url(path) {
+ return `${this.uri}${path}`;
+ }
+ request(method, path, payload, headers = new Headers()) {
+ return __awaiter(this, void 0, void 0, function* () {
+ headers.set('Content-Type', 'application/json');
+ const response = yield fetchOrTimeout(this.url(path), {
+ method,
+ headers,
+ body: cleanStringify(payload),
+ }, this.timeout);
+ let result = yield response.text();
+ try {
+ result = JSON.parse(result);
+ }
+ catch (e) { }
+ if (result.errno) {
+ throw result;
+ }
+ if (!response.ok) {
+ throw {
+ error: 'Unknown error',
+ message: result,
+ errno: 999,
+ code: response.status,
+ };
+ }
+ return result;
+ });
+ }
+ hawkRequest(method, path, token, kind, payload, extraHeaders = new Headers()) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const makeHeaders = () => __awaiter(this, void 0, void 0, function* () {
+ const headers = yield hawk.header(method, this.url(path), token, kind, {
+ payload: cleanStringify(payload),
+ contentType: 'application/json',
+ localtimeOffsetMsec: this.localtimeOffsetMsec,
+ });
+ for (const [name, value] of extraHeaders) {
+ headers.set(name, value);
+ }
+ return headers;
+ });
+ try {
+ return yield this.request(method, path, payload, yield makeHeaders());
+ }
+ catch (e) {
+ if (e.errno === ERRORS.INVALID_TIMESTAMP) {
+ const serverTime = e.serverTime * 1000 || Date.now();
+ this.localtimeOffsetMsec = serverTime - Date.now();
+ return this.request(method, path, payload, yield makeHeaders());
+ }
+ throw e;
+ }
+ });
+ }
+ sessionGet(path, sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('GET', path, sessionToken, tokenType.sessionToken);
+ });
+ }
+ sessionPost(path, sessionToken, payload, headers) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('POST', path, sessionToken, tokenType.sessionToken, payload, headers);
+ });
+ }
+ sessionPut(path, sessionToken, payload, headers) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('PUT', path, sessionToken, tokenType.sessionToken, payload, headers);
+ });
+ }
+ signUp(email, password, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, password);
+ const payloadOptions = (_a) => {
+ var { keys, lang } = _a, rest = __rest(_a, ["keys", "lang"]);
+ return rest;
+ };
+ const payload = Object.assign({ email, authPW: credentials.authPW }, payloadOptions(options));
+ const accountData = yield this.request('POST', pathWithKeys('/account/create', options.keys), payload, langHeader(options.lang));
+ if (options.keys) {
+ accountData.unwrapBKey = credentials.unwrapBKey;
+ }
+ return accountData;
+ });
+ }
+ signIn(email, password, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, password);
+ const payloadOptions = (_a) => {
+ var { keys } = _a, rest = __rest(_a, ["keys"]);
+ return rest;
+ };
+ const payload = Object.assign({ email, authPW: credentials.authPW }, payloadOptions(options));
+ try {
+ const accountData = yield this.request('POST', pathWithKeys('/account/login', options.keys), payload);
+ if (options.keys) {
+ accountData.unwrapBKey = credentials.unwrapBKey;
+ }
+ return accountData;
+ }
+ catch (error) {
+ if (error &&
+ error.email &&
+ error.errno === ERRORS.INCORRECT_EMAIL_CASE &&
+ !options.skipCaseError) {
+ options.skipCaseError = true;
+ options.originalLoginEmail = email;
+ return this.signIn(error.email, password, options);
+ }
+ else {
+ throw error;
+ }
+ }
+ });
+ }
+ verifyCode(uid, code, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/recovery_email/verify_code', Object.assign({ uid,
+ code }, options));
+ });
+ }
+ recoveryEmailStatus(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/recovery_email/status', sessionToken);
+ });
+ }
+ recoveryEmailResendCode(sessionToken, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payloadOptions = (_a) => {
+ var { lang } = _a, rest = __rest(_a, ["lang"]);
+ return rest;
+ };
+ return this.sessionPost('/recovery_email/resend_code', sessionToken, payloadOptions(options), langHeader(options.lang));
+ });
+ }
+ passwordForgotSendCode(email, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payloadOptions = (_a) => {
+ var { lang } = _a, rest = __rest(_a, ["lang"]);
+ return rest;
+ };
+ const payload = Object.assign({ email }, payloadOptions(options));
+ return this.request('POST', '/password/forgot/send_code', payload, langHeader(options.lang));
+ });
+ }
+ passwordForgotResendCode(email, passwordForgotToken, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payloadOptions = (_a) => {
+ var { lang } = _a, rest = __rest(_a, ["lang"]);
+ return rest;
+ };
+ const payload = Object.assign({ email }, payloadOptions(options));
+ return this.hawkRequest('POST', '/password/forgot/resend_code', passwordForgotToken, tokenType.passwordForgotToken, payload, langHeader(options.lang));
+ });
+ }
+ passwordForgotVerifyCode(code, passwordForgotToken, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payload = Object.assign({ code }, options);
+ return this.hawkRequest('POST', '/password/forgot/verify_code', passwordForgotToken, tokenType.passwordForgotToken, payload);
+ });
+ }
+ passwordForgotStatus(passwordForgotToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('GET', '/password/forgot/status', passwordForgotToken, tokenType.passwordForgotToken);
+ });
+ }
+ accountReset(email, newPassword, accountResetToken, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, newPassword);
+ const payloadOptions = (_a) => {
+ var { keys } = _a, rest = __rest(_a, ["keys"]);
+ return rest;
+ };
+ const payload = Object.assign({ authPW: credentials.authPW }, payloadOptions(options));
+ const accountData = yield this.hawkRequest('POST', pathWithKeys('/account/reset', options.keys), accountResetToken, tokenType.accountResetToken, payload);
+ if (options.keys && accountData.keyFetchToken) {
+ accountData.unwrapBKey = credentials.unwrapBKey;
+ }
+ return accountData;
+ });
+ }
+ finishSetup(token, email, newPassword) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, newPassword);
+ const payload = {
+ token,
+ authPW: credentials.authPW,
+ };
+ return yield this.request('POST', '/account/finish_setup', payload);
+ });
+ }
+ verifyAccountThirdParty(code, provider = AUTH_PROVIDER.GOOGLE, metricsContext = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payload = {
+ code,
+ provider,
+ metricsContext,
+ };
+ return yield this.request('POST', '/linked_account/login', payload);
+ });
+ }
+ unlinkThirdParty(sessionToken, providerId) {
+ return __awaiter(this, void 0, void 0, function* () {
+ let provider;
+ switch (providerId) {
+ case 2: {
+ provider = AUTH_PROVIDER.APPLE;
+ break;
+ }
+ default: {
+ provider = AUTH_PROVIDER.GOOGLE;
+ }
+ }
+ return yield this.sessionPost('/linked_account/unlink', sessionToken, {
+ provider,
+ });
+ });
+ }
+ accountKeys(keyFetchToken, unwrapBKey) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield hawk.deriveHawkCredentials(keyFetchToken, 'keyFetchToken');
+ const keyData = yield this.hawkRequest('GET', '/account/keys', keyFetchToken, tokenType.keyFetchToken);
+ const keys = yield crypto.unbundleKeyFetchResponse(credentials.bundleKey, keyData.bundle);
+ return {
+ kA: keys.kA,
+ kB: crypto.unwrapKB(keys.wrapKB, unwrapBKey),
+ };
+ });
+ }
+ accountDestroy(email, password, options = {}, sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, password);
+ const payload = {
+ email,
+ authPW: credentials.authPW,
+ };
+ try {
+ if (sessionToken) {
+ return yield this.sessionPost('/account/destroy', sessionToken, payload);
+ }
+ else {
+ return yield this.request('POST', '/account/destroy', payload);
+ }
+ }
+ catch (error) {
+ if (error &&
+ error.email &&
+ error.errno === ERRORS.INCORRECT_EMAIL_CASE &&
+ !options.skipCaseError) {
+ options.skipCaseError = true;
+ return this.accountDestroy(error.email, password, options, sessionToken);
+ }
+ else {
+ throw error;
+ }
+ }
+ });
+ }
+ accountStatus(uid) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('GET', `/account/status?uid=${uid}`);
+ });
+ }
+ accountStatusByEmail(email) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/account/status', { email });
+ });
+ }
+ accountProfile(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/account/profile', sessionToken);
+ });
+ }
+ account(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/account', sessionToken);
+ });
+ }
+ sessionDestroy(sessionToken, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/session/destroy', sessionToken, options);
+ });
+ }
+ sessionStatus(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/session/status', sessionToken);
+ });
+ }
+ sessionVerifyCode(sessionToken, code, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/session/verify_code', sessionToken, Object.assign({ code }, options));
+ });
+ }
+ sessionResendVerifyCode(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/session/resend_code', sessionToken, {});
+ });
+ }
+ sessionReauth(sessionToken, email, password, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, password);
+ const payloadOptions = (_a) => {
+ var { keys } = _a, rest = __rest(_a, ["keys"]);
+ return rest;
+ };
+ const payload = Object.assign({ email, authPW: credentials.authPW }, payloadOptions(options));
+ try {
+ const accountData = yield this.sessionPost(pathWithKeys('/session/reauth', options.keys), sessionToken, payload);
+ if (options.keys) {
+ accountData.unwrapBKey = credentials.unwrapBKey;
+ }
+ return accountData;
+ }
+ catch (error) {
+ if (error &&
+ error.email &&
+ error.errno === ERRORS.INCORRECT_EMAIL_CASE &&
+ !options.skipCaseError) {
+ options.skipCaseError = true;
+ options.originalLoginEmail = email;
+ return this.sessionReauth(sessionToken, error.email, password, options);
+ }
+ else {
+ throw error;
+ }
+ }
+ });
+ }
+ certificateSign(sessionToken, publicKey, duration, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payload = {
+ publicKey,
+ duration,
+ };
+ return this.sessionPost(`/certificate/sign${options.service
+ ? `?service=${encodeURIComponent(options.service)}`
+ : ''}`, sessionToken, payload);
+ });
+ }
+ passwordChange(email, oldPassword, newPassword, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const oldCredentials = yield this.passwordChangeStart(email, oldPassword);
+ const keys = yield this.accountKeys(oldCredentials.keyFetchToken, oldCredentials.unwrapBKey);
+ const newCredentials = yield crypto.getCredentials(oldCredentials.email, newPassword);
+ const wrapKb = crypto.unwrapKB(keys.kB, newCredentials.unwrapBKey);
+ const sessionToken = options.sessionToken
+ ? (yield hawk.deriveHawkCredentials(options.sessionToken, 'sessionToken'))
+ .id
+ : undefined;
+ const payload = {
+ wrapKb,
+ authPW: newCredentials.authPW,
+ sessionToken,
+ };
+ const accountData = yield this.hawkRequest('POST', pathWithKeys('/password/change/finish', options.keys), oldCredentials.passwordChangeToken, tokenType.passwordChangeToken, payload);
+ if (options.keys && accountData.keyFetchToken) {
+ accountData.unwrapBKey = newCredentials.unwrapBKey;
+ }
+ return accountData;
+ });
+ }
+ passwordChangeStart(email, oldPassword, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const oldCredentials = yield crypto.getCredentials(email, oldPassword);
+ try {
+ const passwordData = yield this.request('POST', '/password/change/start', {
+ email,
+ oldAuthPW: oldCredentials.authPW,
+ });
+ return {
+ authPW: oldCredentials.authPW,
+ unwrapBKey: oldCredentials.unwrapBKey,
+ email: email,
+ keyFetchToken: passwordData.keyFetchToken,
+ passwordChangeToken: passwordData.passwordChangeToken,
+ };
+ }
+ catch (error) {
+ if (error &&
+ error.email &&
+ error.errno === ERRORS.INCORRECT_EMAIL_CASE &&
+ !options.skipCaseError) {
+ options.skipCaseError = true;
+ return this.passwordChangeStart(error.email, oldPassword, options);
+ }
+ else {
+ throw error;
+ }
+ }
+ });
+ }
+ createPassword(sessionToken, email, newPassword) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const newCredentials = yield crypto.getCredentials(email, newPassword);
+ const payload = {
+ authPW: newCredentials.authPW,
+ };
+ return this.sessionPost('/password/create', sessionToken, payload);
+ });
+ }
+ getRandomBytes() {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/get_random_bytes');
+ });
+ }
+ deviceRegister(sessionToken, name, type, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payload = Object.assign({ name,
+ type }, options);
+ return this.sessionPost('/account/device', sessionToken, payload);
+ });
+ }
+ deviceUpdate(sessionToken, id, name, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payload = Object.assign({ id,
+ name }, options);
+ return this.sessionPost('/account/device', sessionToken, payload);
+ });
+ }
+ deviceDestroy(sessionToken, id) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/account/device/destroy', sessionToken, { id });
+ });
+ }
+ deviceList(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/account/devices', sessionToken);
+ });
+ }
+ sessions(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/account/sessions', sessionToken);
+ });
+ }
+ securityEvents(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/securityEvents', sessionToken);
+ });
+ }
+ deleteSecurityEvents(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('DELETE', '/securityEvents', sessionToken, tokenType.sessionToken, {});
+ });
+ }
+ attachedClients(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/account/attached_clients', sessionToken);
+ });
+ }
+ attachedClientDestroy(sessionToken, clientInfo) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/account/attached_client/destroy', sessionToken, {
+ clientId: clientInfo.clientId,
+ deviceId: clientInfo.deviceId,
+ refreshTokenId: clientInfo.refreshTokenId,
+ sessionTokenId: clientInfo.sessionTokenId,
+ });
+ });
+ }
+ sendUnblockCode(email, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/account/login/send_unblock_code', Object.assign({ email }, options));
+ });
+ }
+ rejectUnblockCode(uid, unblockCode) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/account/login/reject_unblock_code', {
+ uid,
+ unblockCode,
+ });
+ });
+ }
+ consumeSigninCode(code, flowId, flowBeginTime, deviceId) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/signinCodes/consume', {
+ code,
+ metricsContext: {
+ deviceId,
+ flowId,
+ flowBeginTime,
+ },
+ });
+ });
+ }
+ createSigninCode(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/signinCodes', sessionToken, {});
+ });
+ }
+ createCadReminder(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/emails/reminders/cad', sessionToken, {});
+ });
+ }
+ recoveryEmails(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/recovery_emails', sessionToken);
+ });
+ }
+ recoveryEmailCreate(sessionToken, email, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recovery_email', sessionToken, Object.assign({ email }, options));
+ });
+ }
+ recoveryEmailDestroy(sessionToken, email) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recovery_email/destroy', sessionToken, { email });
+ });
+ }
+ recoveryEmailSetPrimaryEmail(sessionToken, email) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recovery_email/set_primary', sessionToken, {
+ email,
+ });
+ });
+ }
+ recoveryEmailSecondaryVerifyCode(sessionToken, email, code) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recovery_email/secondary/verify_code', sessionToken, { email, code });
+ });
+ }
+ recoveryEmailSecondaryResendCode(sessionToken, email) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recovery_email/secondary/resend_code', sessionToken, { email });
+ });
+ }
+ createTotpToken(sessionToken, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/totp/create', sessionToken, options);
+ });
+ }
+ deleteTotpToken(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/totp/destroy', sessionToken, {});
+ });
+ }
+ checkTotpTokenExists(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/totp/exists', sessionToken);
+ });
+ }
+ verifyTotpCode(sessionToken, code, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/session/verify/totp', sessionToken, Object.assign({ code }, options));
+ });
+ }
+ replaceRecoveryCodes(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionGet('/recoveryCodes', sessionToken);
+ });
+ }
+ updateRecoveryCodes(sessionToken, recoveryCodes) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPut('/recoveryCodes', sessionToken, { recoveryCodes });
+ });
+ }
+ consumeRecoveryCode(sessionToken, code) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/session/verify/recoveryCode', sessionToken, {
+ code,
+ });
+ });
+ }
+ createRecoveryKey(sessionToken, recoveryKeyId, recoveryData, enabled) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recoveryKey', sessionToken, {
+ recoveryKeyId,
+ recoveryData,
+ enabled,
+ });
+ });
+ }
+ getRecoveryKey(accountResetToken, recoveryKeyId) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('GET', `/recoveryKey/${recoveryKeyId}`, accountResetToken, tokenType.accountResetToken);
+ });
+ }
+ resetPasswordWithRecoveryKey(accountResetToken, email, newPassword, recoveryKeyId, keys, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const credentials = yield crypto.getCredentials(email, newPassword);
+ const newWrapKb = crypto.unwrapKB(keys.kB, credentials.unwrapBKey);
+ const payload = {
+ wrapKb: newWrapKb,
+ authPW: credentials.authPW,
+ sessionToken: options.sessionToken,
+ recoveryKeyId,
+ };
+ const accountData = yield this.hawkRequest('POST', pathWithKeys('/account/reset', options.keys), accountResetToken, tokenType.accountResetToken, payload);
+ if (options.keys && accountData.keyFetchToken) {
+ accountData.unwrapBKey = credentials.unwrapBKey;
+ }
+ return accountData;
+ });
+ }
+ deleteRecoveryKey(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.hawkRequest('DELETE', '/recoveryKey', sessionToken, tokenType.sessionToken, {});
+ });
+ }
+ recoveryKeyExists(sessionToken, email) {
+ return __awaiter(this, void 0, void 0, function* () {
+ if (sessionToken) {
+ return this.sessionPost('/recoveryKey/exists', sessionToken, { email });
+ }
+ return this.request('POST', '/recoveryKey/exists', { email });
+ });
+ }
+ verifyRecoveryKey(sessionToken, recoveryKeyId) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/recoveryKey/verify', sessionToken, {
+ recoveryKeyId,
+ });
+ });
+ }
+ createOAuthCode(sessionToken, clientId, state, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/oauth/authorization', sessionToken, {
+ access_type: options.access_type,
+ acr_values: options.acr_values,
+ client_id: clientId,
+ code_challenge: options.code_challenge,
+ code_challenge_method: options.code_challenge_method,
+ keys_jwe: options.keys_jwe,
+ redirect_uri: options.redirect_uri,
+ response_type: options.response_type,
+ scope: options.scope,
+ state,
+ });
+ });
+ }
+ createOAuthToken(sessionToken, clientId, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/oauth/token', sessionToken, {
+ grant_type: 'fxa-credentials',
+ access_type: options.access_type,
+ client_id: clientId,
+ scope: options.scope,
+ ttl: options.ttl,
+ });
+ });
+ }
+ getOAuthScopedKeyData(sessionToken, clientId, scope) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/account/scoped-key-data', sessionToken, {
+ client_id: clientId,
+ scope,
+ });
+ });
+ }
+ getSubscriptionPlans() {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('GET', '/oauth/subscriptions/plans');
+ });
+ }
+ getActiveSubscriptions(accessToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('GET', '/oauth/subscriptions/active', null, new Headers({
+ authorization: `Bearer ${accessToken}`,
+ }));
+ });
+ }
+ createSupportTicket(accessToken, supportTicket) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.request('POST', '/support/ticket', supportTicket, new Headers({
+ authorization: `Bearer ${accessToken}`,
+ }));
+ });
+ }
+ updateNewsletters(sessionToken, newsletters) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/newsletters', sessionToken, {
+ newsletters,
+ });
+ });
+ }
+ verifyIdToken(idToken, clientId, expiryGracePeriod) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const payload = {
+ id_token: idToken,
+ client_id: clientId,
+ };
+ if (expiryGracePeriod) {
+ payload.expiry_grace_period = expiryGracePeriod;
+ }
+ return this.request('POST', '/oauth/id-token-verify', payload);
+ });
+ }
+ sendPushLoginRequest(sessionToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.sessionPost('/session/verify/send_push', sessionToken, {});
+ });
+ }
+}
+AuthClient.VERSION = 'v1';