UNPKG

@sphereon/did-auth-siop

Version:

Self Issued OpenID V2 (SIOPv2) and OpenID 4 Verifiable Presentations (OID4VP)

139 lines (124 loc) 4.48 kB
import { fetch } from 'cross-fetch' import Debug from 'debug' import { ContentType, SIOPErrors, SIOPResonse } from '../types' const debug = Debug('sphereon:siopv2:http') export const getJson = async <T>( URL: string, opts?: { bearerToken?: string contentType?: string | ContentType accept?: string customHeaders?: HeadersInit exceptionOnHttpErrorStatus?: boolean }, ): Promise<SIOPResonse<T>> => { return await siopFetch(URL, undefined, { method: 'GET', ...opts }) } export const formPost = async <T>( url: string, body: BodyInit, opts?: { bearerToken?: string contentType?: string | ContentType accept?: string customHeaders?: HeadersInit exceptionOnHttpErrorStatus?: boolean }, ): Promise<SIOPResonse<T>> => { return await post(url, body, opts?.contentType ? { ...opts } : { contentType: ContentType.FORM_URL_ENCODED, ...opts }) } export const post = async <T>( url: string, body?: BodyInit, opts?: { bearerToken?: string contentType?: string | ContentType accept?: string customHeaders?: HeadersInit exceptionOnHttpErrorStatus?: boolean }, ): Promise<SIOPResonse<T>> => { return await siopFetch(url, body, { method: 'POST', ...opts }) } const siopFetch = async <T>( url: string, body?: BodyInit, opts?: { method?: string bearerToken?: string contentType?: string | ContentType accept?: string customHeaders?: HeadersInit exceptionOnHttpErrorStatus?: boolean }, ): Promise<SIOPResonse<T>> => { if (!url || url.toLowerCase().startsWith('did:')) { throw Error(`Invalid URL supplied. Expected a http(s) URL. Recieved: ${url}`) } const headers: Record<string, any> = opts?.customHeaders ? opts.customHeaders : {} if (opts?.bearerToken) { headers['Authorization'] = `Bearer ${opts.bearerToken}` } const method = opts?.method ? opts.method : body ? 'POST' : 'GET' const accept = opts?.accept ? opts.accept : 'application/json' headers['Content-Type'] = opts?.contentType ? opts.contentType : method !== 'GET' ? 'application/json' : undefined headers['Accept'] = accept const payload: RequestInit = { method, headers, body, } debug(`START fetching url: ${url}`) if (body) { debug(`Body:\r\n${JSON.stringify(body)}`) } debug(`Headers:\r\n${JSON.stringify(payload.headers)}`) const origResponse = await fetch(url, payload) const clonedResponse = origResponse.clone() const success = origResponse && origResponse.status >= 200 && origResponse.status < 400 const textResponseBody = await clonedResponse.text() const isJSONResponse = (accept === 'application/json' || origResponse.headers.get('Content-Type') === 'application/json') && textResponseBody.trim().startsWith('{') const responseBody = isJSONResponse ? JSON.parse(textResponseBody) : textResponseBody if (success || opts?.exceptionOnHttpErrorStatus) { debug(`${success ? 'success' : 'error'} status: ${clonedResponse.status}, body:\r\n${JSON.stringify(responseBody)}`) } else { console.warn(`${success ? 'success' : 'error'} status: ${clonedResponse.status}, body:\r\n${JSON.stringify(responseBody)}`) } if (!success && opts?.exceptionOnHttpErrorStatus) { const error = JSON.stringify(responseBody) throw new Error(error === '{}' ? '{"error": "not found"}' : error) } debug(`END fetching url: ${url}`) return { origResponse, successBody: success ? responseBody : undefined, errorBody: !success ? responseBody : undefined, } } export const getWithUrl = async <T>(url: string, textResponse?: boolean): Promise<T> => { // try { const response = await fetch(url) if (response.status >= 400) { return Promise.reject(Error(`${SIOPErrors.RESPONSE_STATUS_UNEXPECTED} ${response.status}:${response.statusText} URL: ${url}`)) } if (textResponse === true) { return (await response.text()) as unknown as T } return await response.json() /*} catch (e) { return Promise.reject(Error(`${(e as Error).message}`)); }*/ } export const fetchByReferenceOrUseByValue = async <T>(referenceURI: string, valueObject: T, textResponse?: boolean): Promise<T> => { let response: T = valueObject if (referenceURI) { try { response = await getWithUrl(referenceURI, textResponse) } catch (e) { console.log(e) throw new Error(`${SIOPErrors.REG_PASS_BY_REFERENCE_INCORRECTLY}: ${(e as Error).message}, URL: ${referenceURI}`) } } return response }