From 5c2137fb9d0f53a0dafc2a8d52f4256a12174303 Mon Sep 17 00:00:00 2001 From: Leandro Costa Date: Mon, 27 Mar 2023 20:49:33 -0300 Subject: [PATCH] feat: adiciona generics para o response type --- src/lhisp-oauth-client.ts | 321 +++++++++++++++++++++----------------- 1 file changed, 176 insertions(+), 145 deletions(-) diff --git a/src/lhisp-oauth-client.ts b/src/lhisp-oauth-client.ts index ae26866..72f7644 100644 --- a/src/lhisp-oauth-client.ts +++ b/src/lhisp-oauth-client.ts @@ -1,164 +1,195 @@ -import qs from 'querystring'; -import https from 'https'; -import axios, { AxiosRequestConfig } from 'axios'; -import { - AccessToken, ContentType, defaultAuthContentType, - defaultAuthHeaderName, - defaultGrantType, - defaultTokenHeaderName, - ExecutarRequestParams, - LhispOauthClientConstructorParams, +import qs from "querystring"; +import https from "https"; +import axios, { AxiosRequestConfig } from "axios"; +import { + AccessToken, + ContentType, + defaultAuthContentType, + defaultAuthHeaderName, + defaultGrantType, + defaultTokenHeaderName, + ExecutarRequestParams, + LhispOauthClientConstructorParams, } from "./lhisp-oauth-client.t"; export class LhispOauthClient { - protected authUrl: string; - protected apiUrl: string; - protected clientId: string; - protected clientSecret: string; - protected authHeaderName: string; - protected tokenHeaderName: string; - protected authContentType: ContentType; - protected certificado?: string; - protected senhaCertificado?: string; - protected authScope?: string; - protected headers?: Headers; - protected grantType?: string; - protected agent: https.Agent; - protected accessToken?: AccessToken; - protected refreshToken?: AccessToken; - protected sendAuthCredentialsOnRequestBody?: boolean; + protected authUrl: string; + protected apiUrl: string; + protected clientId: string; + protected clientSecret: string; + protected authHeaderName: string; + protected tokenHeaderName: string; + protected authContentType: ContentType; + protected certificado?: string; + protected senhaCertificado?: string; + protected authScope?: string; + protected headers?: Headers; + protected grantType?: string; + protected agent: https.Agent; + protected accessToken?: AccessToken; + protected refreshToken?: AccessToken; + protected sendAuthCredentialsOnRequestBody?: boolean; - constructor(params: LhispOauthClientConstructorParams) { - if (params.certificado) { - this.agent = new https.Agent({ - pfx: params.certificado, - passphrase: params.senhaCertificado, - rejectUnauthorized: false, - }); - } else { - this.agent = new https.Agent({ - rejectUnauthorized: false - }); - } - - - this.certificado = params.certificado; - this.headers = (params.headers ? params.headers : {}) as any as Headers; - this.apiUrl = params.apiUrl; - this.authUrl = params.authUrl; - this.authScope = params.authScope; - this.grantType = params.grantType || defaultGrantType; - this.authContentType = params.authContentType || defaultAuthContentType; - this.clientId = params.clientId; - this.clientSecret = params.clientSecret; - this.authHeaderName = params.authHeaderName || defaultAuthHeaderName; - this.tokenHeaderName = params.tokenHeaderName || defaultTokenHeaderName; - this.sendAuthCredentialsOnRequestBody = params.sendAuthCredentialsOnRequestBody; + constructor(params: LhispOauthClientConstructorParams) { + if (params.certificado) { + this.agent = new https.Agent({ + pfx: params.certificado, + passphrase: params.senhaCertificado, + rejectUnauthorized: false, + }); + } else { + this.agent = new https.Agent({ + rejectUnauthorized: false, + }); } - getAuthHeaderValue(): string { - return `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`; + this.certificado = params.certificado; + this.headers = (params.headers ? params.headers : {}) as any as Headers; + this.apiUrl = params.apiUrl; + this.authUrl = params.authUrl; + this.authScope = params.authScope; + this.grantType = params.grantType || defaultGrantType; + this.authContentType = params.authContentType || defaultAuthContentType; + this.clientId = params.clientId; + this.clientSecret = params.clientSecret; + this.authHeaderName = params.authHeaderName || defaultAuthHeaderName; + this.tokenHeaderName = params.tokenHeaderName || defaultTokenHeaderName; + this.sendAuthCredentialsOnRequestBody = params.sendAuthCredentialsOnRequestBody; + } + + getAuthHeaderValue(): string { + return `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`; + } + + parseData({ data, contentType = ContentType.APPLICATION_JSON }: { data: any; contentType: string }) { + if (!data || Object.keys(data).length === 0) return undefined; + + switch (contentType) { + case ContentType.APPLICATION_JSON: + return JSON.stringify(data); + case ContentType.APPLICATION_X_WWW_FORM_URLENCODED: + return qs.stringify(data); + default: + throw new Error(`Content Type Inválido: [${contentType}]`); + } + } + + isTokenValid(token: AccessToken) { + if (!token) return false; + if (!token.created_at) return false; + const timeDiff = (Date.now() - token.created_at) / 1000; + return timeDiff < token.expires_in - 10; + } + + async getAccessToken(): Promise { + if (this.accessToken && this.isTokenValid(this.accessToken)) { + return this.accessToken; } - parseData({ data, contentType = ContentType.APPLICATION_JSON }: { data: any, contentType: string }) { - if(!data || Object.keys(data).length===0) return undefined; + // TODO: Implementar Refresh Token. - switch (contentType) { - case ContentType.APPLICATION_JSON: return JSON.stringify(data); - case ContentType.APPLICATION_X_WWW_FORM_URLENCODED: return qs.stringify(data); - default: - throw new Error(`Content Type Inválido: [${contentType}]`); - } + let authRequestOpt: AxiosRequestConfig = { + method: "POST", + url: this.authUrl, + httpsAgent: this.agent, + headers: { + [this.authHeaderName]: this.getAuthHeaderValue(), + "Content-Type": this.authContentType, + }, + data: {}, + }; + + if (this.grantType) authRequestOpt.data.grant_type = this.grantType; + if (this.authScope) authRequestOpt.data.scope = this.authScope; + + if (this.sendAuthCredentialsOnRequestBody) { + if (this.clientId) authRequestOpt.data.client_id = this.clientId; + if (this.clientSecret) authRequestOpt.data.client_secret = this.clientSecret; } - isTokenValid(token: AccessToken){ - if(!token) return false; - if(!token.created_at) return false; - const timeDiff = (Date.now() - token.created_at) / 1000; - return timeDiff < token.expires_in - 10; + authRequestOpt.data = this.parseData({ + data: authRequestOpt.data, + contentType: this.authContentType, + }); + const response = await axios.request(authRequestOpt); + return this.buildAccessToken(response.data); + } + + buildAccessToken(data: Omit): AccessToken { + this.accessToken = { + ...data, + created_at: Date.now(), + }; + + return this.accessToken; + } + + getAuthToken() { + return `${this.accessToken?.token_type} ${this.accessToken?.access_token}`; + } + + async executarRequest({ + method, + path, + data, + params, + contentType = ContentType.APPLICATION_JSON, + }: ExecutarRequestParams): Promise { + await this.getAccessToken(); + if (!this.accessToken?.token_type) { + console.log("## LHOAUTH2 NO TOKEN ?:", this.accessToken); } - async getAccessToken() : Promise { - if(this.accessToken && this.isTokenValid(this.accessToken)) { - return this.accessToken; - } + let headers = { + "Content-Type": contentType, + [this.tokenHeaderName]: this.getAuthToken(), + // ...this.headers + }; - // TODO: Implementar Refresh Token. + const response = await axios.request({ + method, + url: `${this.apiUrl}${path}`, + httpsAgent: this.agent, + headers, + data, + params, + }); - let authRequestOpt: AxiosRequestConfig = { - method: 'POST', - url: this.authUrl, - httpsAgent: this.agent, - headers: { - [this.authHeaderName]: this.getAuthHeaderValue(), - 'Content-Type': this.authContentType, - }, - data: {}, - } + return response.data; + } - if(this.grantType) authRequestOpt.data.grant_type = this.grantType; - if(this.authScope) authRequestOpt.data.scope = this.authScope; + async get({ path, contentType = ContentType.APPLICATION_JSON, params }: ExecutarRequestParams) { + return this.executarRequest({ + method: "GET", + path, + contentType, + params, + }); + } - if(this.sendAuthCredentialsOnRequestBody) { - if(this.clientId) authRequestOpt.data.client_id = this.clientId; - if(this.clientSecret) authRequestOpt.data.client_secret = this.clientSecret; - } + async put({ path, data, contentType = ContentType.APPLICATION_JSON }: ExecutarRequestParams) { + return this.executarRequest({ + method: "PUT", + path, + data, + contentType, + }); + } - authRequestOpt.data = this.parseData({ data: authRequestOpt.data, contentType: this.authContentType }); - const response = await axios.request(authRequestOpt); - return this.buildAccessToken(response.data); - } + async post({ path, data, contentType = ContentType.APPLICATION_JSON }: ExecutarRequestParams) { + return this.executarRequest({ + method: "POST", + path, + data, + contentType, + }); + } - buildAccessToken(data: Omit): AccessToken{ - this.accessToken = { - ...data, - created_at: Date.now() - }; - - return this.accessToken; - } - - getAuthToken(){ - return `${this.accessToken?.token_type} ${this.accessToken?.access_token}`; - } - - async executarRequest({ method, path, data, params, contentType = ContentType.APPLICATION_JSON } : ExecutarRequestParams) { - await this.getAccessToken(); - if (!this.accessToken?.token_type) { - console.log("## LHOAUTH2 NO TOKEN ?:", this.accessToken); - } - - let headers = { - 'Content-Type': contentType, - [this.tokenHeaderName]: this.getAuthToken(), - // ...this.headers - }; - - const response = await axios.request({ - method, - url: `${this.apiUrl}${path}`, - httpsAgent: this.agent, - headers, - data, - params - }); - - return response.data; - } - - async get({ path, contentType = ContentType.APPLICATION_JSON, params }: ExecutarRequestParams) { - return this.executarRequest({ method: 'GET', path, contentType, params }); - } - - async put({ path, data, contentType = ContentType.APPLICATION_JSON }: ExecutarRequestParams) { - return this.executarRequest({ method: 'PUT', path, data, contentType }); - } - - async post({ path, data, contentType = ContentType.APPLICATION_JSON }: ExecutarRequestParams) { - return this.executarRequest({ method: 'POST', path, data, contentType }); - } - - async delete({ path, contentType = ContentType.APPLICATION_JSON }: ExecutarRequestParams) { - return this.executarRequest({ method: 'DELETE', path, contentType }); - } -} \ No newline at end of file + async delete({ path, contentType = ContentType.APPLICATION_JSON }: ExecutarRequestParams) { + return this.executarRequest({ + method: "DELETE", + path, + contentType, + }); + } +}