UNPKG

@foxy.io/sdk

Version:

Universal SDK for a full server-side and a limited in-browser access to Foxy hAPI.

177 lines (176 loc) 8.11 kB
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()); }); }; import { Request, fetch } from 'cross-fetch'; import { v8n } from '../core/v8n.js'; import * as Core from '../core/index.js'; /** * Customer API for adding custom functionality to websites and web apps with our Customer Portal. * * **IMPORTANT**: this client is not compatible with the beta version of Customer API. * If you're still on beta, please consider updating your code to the latest stable version. * You can use @foxy.io/sdk prior to 1.0.0-beta.15 or a custom API client until you transition. */ export class API extends Core.API { constructor(params) { super(Object.assign(Object.assign({}, params), { fetch: (...args) => this.__fetch(...args) })); } /** * Creates a Customer Portal session for a customer with the given credentials. * Incorrect email and password will trigger `Core.API.AuthError` with code `UNAUTHORIZED`. * * @param credentials Customer email and password (one-time code). */ signIn(credentials) { return __awaiter(this, void 0, void 0, function* () { API.v8n.credentials.check(credentials); const response = yield this.fetch(new URL('./authenticate', this.base).toString(), { body: JSON.stringify(credentials), method: 'POST', }); if (response.ok) { const session = yield response.json(); const storedSession = Object.assign(Object.assign({}, session), { date_created: new Date().toISOString() }); this.storage.setItem(API.SESSION, JSON.stringify(storedSession)); } else { const code = response.status === 401 ? 'UNAUTHORIZED' : 'UNKNOWN'; throw new Core.API.AuthError({ code }); } }); } /** * Creates a new customer account with the given credentials. * If the email is already taken, `Core.API.AuthError` with code `UNAVAILABLE` will be thrown. * If customer registration is disabled, `Core.API.AuthError` with code `UNAUTHORIZED` will be thrown. * If the provided form data is invalid (e.g. captcha is expired), `Core.API.AuthError` with code `INVALID_FORM` will be thrown. * * @param params Customer information. */ signUp(params) { return __awaiter(this, void 0, void 0, function* () { API.v8n.signUpParams.check(params); const url = new URL('./sign_up', this.base); const response = yield this.fetch(url.toString(), { method: 'POST', body: JSON.stringify(params), }); if (!response.ok) { if (response.status === 400) throw new Core.API.AuthError({ code: 'INVALID_FORM' }); if (response.status === 401) throw new Core.API.AuthError({ code: 'UNAUTHORIZED' }); if (response.status === 403) throw new Core.API.AuthError({ code: 'UNAVAILABLE' }); throw new Core.API.AuthError({ code: 'UNKNOWN' }); } }); } /** * Initiates password reset for a customer with the given email. * If such customer exists, they will receive an email from Foxy with further instructions. * * @param params Password reset parameters. * @param params.email Customer email. */ sendPasswordResetEmail(params) { return __awaiter(this, void 0, void 0, function* () { API.v8n.email.check(params.email); const response = yield this.fetch(new URL('./forgot_password', this.base).toString(), { body: JSON.stringify(params), method: 'POST', }); if (!response.ok) throw new Core.API.AuthError({ code: 'UNKNOWN' }); }); } /** Destroys current session and clears local session data. */ signOut() { return __awaiter(this, void 0, void 0, function* () { const response = yield this.fetch(new URL('./authenticate', this.base).toString(), { method: 'DELETE' }); if (!response.ok) throw new Core.API.AuthError({ code: 'UNKNOWN' }); this.storage.clear(); this.cache.clear(); }); } /** * When logged in with a temporary password, this property getter will return `true`. * Will return `false` if password reset is not required or if the session has not been * initiated, or if the session was initiated before the introduction of this feature. * * @returns {boolean} Password reset requirement. */ get usesTemporaryPassword() { const session = this.storage.getItem(API.SESSION); if (session) return !!JSON.parse(session).force_password_reset; return false; } set usesTemporaryPassword(value) { API.v8n.boolean.check(value); const session = this.storage.getItem(API.SESSION); if (session) { const storedSession = JSON.parse(session); storedSession.force_password_reset = value; this.storage.setItem(API.SESSION, JSON.stringify(storedSession)); } } __fetch(input, init) { var _a; return __awaiter(this, void 0, void 0, function* () { let session = JSON.parse((_a = this.storage.getItem(API.SESSION)) !== null && _a !== void 0 ? _a : 'null'); const request = new Request(input, init); if (session !== null) { const expiresAt = new Date(session.date_created).getTime() + session.expires_in * 1000; const now = Date.now(); if (expiresAt < now) { this.console.info('Session has expired, signing out.'); this.storage.clear(); this.cache.clear(); session = null; } else { request.headers.set('Authorization', `Bearer ${session.session_token}`); } } request.headers.set('Content-Type', 'application/json'); request.headers.set('FOXY-API-VERSION', '1'); this.console.trace(`${request.method} ${request.url}`); const response = yield fetch(request); if (session && response.ok) { const refreshedSession = Object.assign(Object.assign({}, session), { date_created: new Date().toISOString() }); this.storage.setItem(API.SESSION, JSON.stringify(refreshedSession)); } return response; }); } } /** Storage key for session data. */ API.SESSION = 'session'; /** Validators for the method arguments in this class (internal). */ API.v8n = Object.assign({}, Core.API.v8n, { signUpParams: v8n().schema({ verification: v8n().schema({ token: v8n().string(), type: v8n().passesAnyOf(v8n().exact('hcaptcha')), }), first_name: v8n().optional(v8n().string().maxLength(50)), last_name: v8n().optional(v8n().string().maxLength(50)), password: v8n().string().maxLength(50), email: v8n().string().maxLength(100), }), credentials: v8n().schema({ email: v8n().string(), newPassword: v8n().optional(v8n().string()), password: v8n().string(), }), boolean: v8n().boolean(), email: v8n().string(), });