UNPKG

@tak-ps/node-tak

Version:

Lightweight JavaScript library for communicating with TAK Server

69 lines (54 loc) 2.31 kB
import Err from '@openaddresses/batch-error'; import { Type, Static } from '@sinclair/typebox'; import Commands from '../commands.js'; export const LoginInput = Type.Object({ username: Type.String(), password: Type.String() }) export const TokenContents = Type.Object({ sub: Type.String(), aud: Type.String(), nbf: Type.Number(), exp: Type.Number(), iat: Type.Number() }) export default class OAuthCommands extends Commands { schema = {} async cli(): Promise<object | string> { throw new Error('Unsupported Subcommand'); } parse(jwt: string): Static<typeof TokenContents>{ const split = Buffer.from(jwt, 'base64').toString().split('}').map((ext) => { return ext + '}'}); if (split.length < 2) throw new Err(500, null, 'Unexpected TAK JWT Format'); const contents: { sub: string; aud: string; nbf: number; exp: number; iat: number; } = JSON.parse(split[1]); return contents; } async login(query: Static<typeof LoginInput>): Promise<{ token: string; contents: Static<typeof TokenContents> }> { const url = new URL(`/oauth/token`, this.api.url); url.searchParams.append('grant_type', 'password'); url.searchParams.append('username', query.username); url.searchParams.append('password', query.password); const authres = await this.api.fetch(url, { method: 'POST' }, true); const text = await authres.text(); if (authres.status === 401) { throw new Err(400, new Error(text), 'TAK Server reports incorrect Username or Password'); } else if (!authres.ok) { throw new Err(400, new Error(`Status: ${authres.status}: ${text}`), 'Non-200 Response from Auth Server - Token'); } const body: any = JSON.parse(text); if (body.error === 'invalid_grant' && body.error_description.startsWith('Bad credentials')) { throw new Err(400, null, 'Invalid Username or Password'); } else if (body.error || !body.access_token) { throw new Err(500, new Error(body.error_description), 'Unknown Login Error'); } return { token: body.access_token, contents: this.parse(body.access_token) }; } }