UNPKG

@jorsek/ezd-client

Version:
189 lines (163 loc) 6.24 kB
import Axios, { AxiosInstance, AxiosRequestConfig } from "axios"; const rateLimit = require("axios-rate-limit"); import { parseCookies } from "nookies"; import "reflect-metadata"; import { getUserTokens } from "./browser_auth/auth"; import { Config } from "./Config"; import { Content } from "./resources/Content"; import { Contribute } from "./resources/Contribute"; import { Search } from "./resources/Search"; import { API_Config } from "./Types"; export interface IClientArgs { org: string; token: string; rootMapId: string; timeout?: number; scheme?: string; hostname?: string; env?: string; content_root?: string; loginRedirect?: string; loginRequired?: boolean; interceptors?: Array<(axios: AxiosInstance) => void>; rateLimit?: { maxRequests?: number; maxRPS: number; } } const EZD_CLIENT_VERSION = "0.1.0"; const API_VERSION = "v1"; export default class Client { public readonly base_url: string; public content_axios: AxiosInstance; public contribute_axios: AxiosInstance; public content: Content; public search: Search; public contribute: Contribute; public content_service_token: string; public initial_args: IClientArgs; constructor(args: IClientArgs) { const { org, token, rootMapId, timeout = 3000, scheme = "https://", hostname = "content.easydita.com", env = "latest", content_root= "content", interceptors = [], rateLimit: rateLimitConfig = { maxRPS: 5, maxRequests: 2 } } = args; this.initial_args = args; if (!org) { throw new Error("easyDITA org not set"); } if (!token) { throw new Error("easyDITA token not set"); } if (!rootMapId) { throw new Error("easyDITA rootMapId not set"); } this.base_url = `${scheme}${hostname}/org/${org}/env/${env}/map/${rootMapId}/`; this.content_service_token = token; const config: AxiosRequestConfig = { baseURL: this.base_url, timeout, // withCredentials: true, headers: { // "X-EZD-Client": "JS/" + EZD_CLIENT_VERSION, }, }; this.content_axios = rateLimit(Axios.create(config), rateLimitConfig); this.content_axios.interceptors.request.use(intercepted_config => { if (!intercepted_config.params) { intercepted_config.params = {}; } // intercepted_config.headers["Content-Type"] = "application/text"; intercepted_config.params.token = this.user_token() ? this.user_token() : this.content_service_token; intercepted_config.params.link_root = content_root; return intercepted_config; }); interceptors.forEach(interceptor => interceptor(this.content_axios)); this.contribute_axios = Axios.create(config); this.contribute_axios.interceptors.request.use(intercepted_config => { if (!intercepted_config.params) { intercepted_config.params = {}; } intercepted_config.params.rootMapId = rootMapId; intercepted_config.params.token = this.user_token(); return intercepted_config; }); const portal_config = new Config(this.content_axios); this.content = new Content({ axios: this.content_axios, config: portal_config }); this.search = new Search({ axios: this.content_axios, rootMapId, config: portal_config }); this.contribute = new Contribute({ axios: this.contribute_axios, config: portal_config }); } public iframe_url() { let s = this.base_url; s = s.replace("https://", ""); s = s.replace("http://", ""); return s; } public user_token() { if (typeof window !== "undefined") { return getUserTokens().idToken; } else { return null; } } public async login() { // create an ezd session so the editor will load without asking user to login first const response = await this.content_axios.post("/auth"); } public async prepare(args): Promise<Client> { const redirect_path = args.req ? `${args.req.protocol}://${args.req.get("host")}${args.req.path}` : `${window.location.protocol}//${window.location.host}${window.location.pathname}`; const cookies = args.req ? args.req.cookies : parseCookies(); const token = (args.req && args.req.query.portal_auth_token) || (cookies && cookies.portal_auth_token); // Make sure to keep this order -- query param overrides cookie const requireLogin = () => { const destination = `${this.initial_args.loginRedirect}?redirect_to=${encodeURI(redirect_path)}`; if (args.res) { return args.res.redirect(destination); } else { window.location.href = destination; return; } }; if (!token) { if (this.initial_args.loginRequired) { return requireLogin(); } else { return this; } } try { const client = new Client({ ...this.initial_args, token, }); await client.content.getSections(); if (args.req && args.req.query.portal_auth_token) { args.res.cookie("portal_auth_token", args.req.query.portal_auth_token, {path: "/", domain: args.req.hostname}); } return client; } catch (e) { if (e.response && e.response.status === 403) { if (args.res) { args.res.clearCookie("portal_auth_token"); } if (this.initial_args.loginRedirect) { return requireLogin(); } return new Client(this.initial_args); } else { throw e; } } } }