diff --git a/src/services/flowaccount.ts b/src/services/flowaccount.ts new file mode 100644 index 0000000..f434303 --- /dev/null +++ b/src/services/flowaccount.ts @@ -0,0 +1,52 @@ +if (!process.env.FLOW_ACCOUNT_URL) throw new Error("Require FLOW_ACCOUNT_URL"); +if (!process.env.FLOW_ACCOUNT_CLIENT_ID) throw new Error("Require FLOW_ACCOUNT_CLIENT_ID"); +if (!process.env.FLOW_ACCOUNT_CLIENT_SECRET) throw new Error("Require FLOW_ACCOUNT_CLIENT_SECRET"); +if (!process.env.FLOW_ACCOUNT_CLIENT_GRANT_TYPE) { + throw new Error("Require FLOW_ACCOUNT_CLIENT_GRANT_TYPE"); +} +if (!process.env.FLOW_ACCOUNT_CLIENT_SCOPE) throw new Error("Require FLOW_ACCOUNT_CLIENT_SCOPE"); + +const api = process.env.FLOW_ACCOUNT_URL; +const clientId = process.env.FLOW_ACCOUNT_CLIENT_ID; +const clientSecret = process.env.FLOW_ACCOUNT_CLIENT_SECRET; +const clientGrantType = process.env.FLOW_ACCOUNT_CLIENT_GRANT_TYPE; +const clientScope = process.env.FLOW_ACCOUNT_CLIENT_SCOPE; + +let token: string = ""; +let tokenExpire: number = Date.now(); + +const flowaccount = { + auth: async () => { + // Get new token if it is expiring soon (30s). + if (token && Date.now() < tokenExpire + 30 * 1000) return { token, tokenExpire }; + + const payload = { + ["client_id"]: clientId, + ["client_secret"]: clientSecret, + ["grant_type"]: clientGrantType, + ["scope"]: clientScope, + }; + + const res = await fetch(api + "/token", { + method: "POST", + headers: { + ["Content-Type"]: "application/x-www-form-urlencoded", + }, + body: new URLSearchParams(payload), + }); + + if (!res.ok) throw new Error("Cannot connect to flowaccount: " + (await res.text())); + + const body: { + access_token: string; + expires_in: number; + } = await res.json(); + + token = body.access_token; + tokenExpire = Date.now() + body.expires_in * 1000; + + return { token, tokenExpire }; + }, +}; + +export default flowaccount;