@marcelo-cheruti/jwtgcp-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/package.json +19 -0
- package/src/authModule.js +126 -0
package/README.md
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@marcelo-cheruti/jwtgcp-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "src/authModule.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"src/authModule.js"
|
|
8
|
+
],
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "Marcelo Cheruti Caetano",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"axios": "^1.13.4",
|
|
14
|
+
"axios-retry": "^4.5.0",
|
|
15
|
+
"dotenv": "^17.2.3",
|
|
16
|
+
"jsonwebtoken": "^9.0.3",
|
|
17
|
+
"uuid": "^13.0.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import axiosRetry from "axios-retry";
|
|
3
|
+
import jwt from "jsonwebtoken";
|
|
4
|
+
import { v4 as uuidv4 } from "uuid";
|
|
5
|
+
|
|
6
|
+
axiosRetry(axios, { retries: 3, retryDelay: axiosRetry.exponentialDelay });
|
|
7
|
+
|
|
8
|
+
let GLOBAL_ACCESS_TOKEN = null;
|
|
9
|
+
let _config = null;
|
|
10
|
+
|
|
11
|
+
export function initAuth(config) {
|
|
12
|
+
const required = [
|
|
13
|
+
"clientId",
|
|
14
|
+
"clientSecret",
|
|
15
|
+
"apiKey",
|
|
16
|
+
"applicationId",
|
|
17
|
+
"companyId",
|
|
18
|
+
"userId",
|
|
19
|
+
"authorizeUrl",
|
|
20
|
+
"tokenUrl",
|
|
21
|
+
];
|
|
22
|
+
const missing = required.filter((key) => !config[key]);
|
|
23
|
+
|
|
24
|
+
if (missing.length > 0) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`[Config Error] the rquired fields is missing ${missing.join(", ")}`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
_config = config;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function authFlow() {
|
|
34
|
+
if (!_config) {
|
|
35
|
+
throw new Error("[Config Error] the config is not initialized");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const requestGuid = uuidv4();
|
|
40
|
+
|
|
41
|
+
// 1. Chamada para Authorize para obter o 'code'
|
|
42
|
+
const authRes = await axios.post(
|
|
43
|
+
_config.authorizeUrl,
|
|
44
|
+
{
|
|
45
|
+
clientId: _config.clientId,
|
|
46
|
+
clientSecret: _config.clientSecret,
|
|
47
|
+
grantType: "client_credentials",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
headers: {
|
|
51
|
+
"X-Company-Id": _config.companyId,
|
|
52
|
+
"X-Application-Id": _config.applicationId,
|
|
53
|
+
"X-Trace-Id": requestGuid,
|
|
54
|
+
"X-User-Id": _config.userId,
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
},
|
|
57
|
+
params: {
|
|
58
|
+
key: process.env.APIKEY,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const code = authRes.data.code;
|
|
64
|
+
|
|
65
|
+
// 2. Chamada para Token passando o 'code'
|
|
66
|
+
const tokenRes = await axios.post(
|
|
67
|
+
process.env.TOKEN_URL,
|
|
68
|
+
{
|
|
69
|
+
code: code,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
headers: {
|
|
73
|
+
"X-Company-Id": _config.companyId,
|
|
74
|
+
"X-Application-Id": _config.applicationId,
|
|
75
|
+
"X-Trace-Id": requestGuid,
|
|
76
|
+
"X-User-Id": _config.userId,
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
},
|
|
79
|
+
params: {
|
|
80
|
+
key: _config.apiKey,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const token = tokenRes.data.token;
|
|
86
|
+
return token;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(
|
|
89
|
+
"Erro na autenticação:",
|
|
90
|
+
error.response?.data || error.message,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function getToken() {
|
|
96
|
+
if (!_config) {
|
|
97
|
+
throw new Error("[Config Error] the config is not initialized");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
console.log("Valida token global");
|
|
101
|
+
if (GLOBAL_ACCESS_TOKEN) {
|
|
102
|
+
const decoded = jwt.decode(GLOBAL_ACCESS_TOKEN);
|
|
103
|
+
|
|
104
|
+
const now = Math.floor(Date.now() / 1000);
|
|
105
|
+
|
|
106
|
+
const hasExpValid = decoded.exp && decoded.exp > now;
|
|
107
|
+
//const hasIssValid = decoded.iss === process.env.JWT_ISSUER;
|
|
108
|
+
//const hasSubValid = decoded.sub === process.env.JWT_SUBJECT;
|
|
109
|
+
//const hasAudValid = decoded.aud === process.env.JWT_AUDIENCE;
|
|
110
|
+
//const hasCustomValid = decoded.minha_claim === "valor_esperado";
|
|
111
|
+
|
|
112
|
+
if (!hasExpValid) {
|
|
113
|
+
console.log("Claims inválidos ou token expirado.");
|
|
114
|
+
GLOBAL_ACCESS_TOKEN = await authFlow();
|
|
115
|
+
console.log("Novo token gerado e armazenado.");
|
|
116
|
+
return GLOBAL_ACCESS_TOKEN;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log("Usou o token do cache");
|
|
120
|
+
return GLOBAL_ACCESS_TOKEN;
|
|
121
|
+
} else {
|
|
122
|
+
GLOBAL_ACCESS_TOKEN = await authFlow();
|
|
123
|
+
console.log("Token inexistente, novo token gerado e armazenado.");
|
|
124
|
+
return GLOBAL_ACCESS_TOKEN;
|
|
125
|
+
}
|
|
126
|
+
}
|