@neetru/sdk 3.6.0 → 3.8.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/CHANGELOG.md +104 -0
- package/README.md +66 -1
- package/dist/ai.cjs +298 -391
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.mjs +298 -391
- package/dist/auth.cjs +3717 -5005
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +3714 -5002
- package/dist/build-guard.cjs +101 -119
- package/dist/build-guard.mjs +91 -109
- package/dist/catalog.cjs +220 -225
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +220 -225
- package/dist/checkout.cjs +307 -323
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +306 -322
- package/dist/db-react.cjs +59 -87
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db-react.mjs +56 -84
- package/dist/db.cjs +2128 -3014
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +2141 -3027
- package/dist/entitlements.cjs +19 -20
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +19 -20
- package/dist/errors.cjs +16 -12
- package/dist/errors.d.cts +59 -3
- package/dist/errors.d.ts +59 -3
- package/dist/errors.mjs +15 -12
- package/dist/firestore-compat.cjs +241 -297
- package/dist/firestore-compat.d.cts +1 -1
- package/dist/firestore-compat.d.ts +1 -1
- package/dist/firestore-compat.mjs +215 -271
- package/dist/index.cjs +3942 -5134
- package/dist/index.d.cts +181 -5
- package/dist/index.d.ts +181 -5
- package/dist/index.mjs +4040 -5239
- package/dist/mobile.cjs +459 -344
- package/dist/mobile.d.cts +59 -4
- package/dist/mobile.d.ts +59 -4
- package/dist/mobile.mjs +459 -344
- package/dist/mocks.cjs +319 -447
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.mjs +313 -441
- package/dist/notifications.cjs +296 -317
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +295 -316
- package/dist/react.cjs +557 -707
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +547 -697
- package/dist/support.cjs +402 -328
- package/dist/support.d.cts +29 -3
- package/dist/support.d.ts +29 -3
- package/dist/support.mjs +401 -328
- package/dist/telemetry.cjs +267 -304
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +267 -304
- package/dist/{types-Du_iioJ7.d.cts → types-D-9bjlM0.d.cts} +74 -1
- package/dist/{types-BPATkXYu.d.ts → types-bVztFQTI.d.ts} +74 -1
- package/dist/usage.cjs +233 -230
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +233 -230
- package/dist/webhooks.cjs +328 -362
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +325 -359
- package/package.json +5 -3
- package/dist/ai.cjs.map +0 -1
- package/dist/ai.mjs.map +0 -1
- package/dist/auth.cjs.map +0 -1
- package/dist/auth.mjs.map +0 -1
- package/dist/build-guard.cjs.map +0 -1
- package/dist/build-guard.mjs.map +0 -1
- package/dist/catalog.cjs.map +0 -1
- package/dist/catalog.mjs.map +0 -1
- package/dist/checkout.cjs.map +0 -1
- package/dist/checkout.mjs.map +0 -1
- package/dist/db-react.cjs.map +0 -1
- package/dist/db-react.mjs.map +0 -1
- package/dist/db.cjs.map +0 -1
- package/dist/db.mjs.map +0 -1
- package/dist/entitlements.cjs.map +0 -1
- package/dist/entitlements.mjs.map +0 -1
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.mjs.map +0 -1
- package/dist/firestore-compat.cjs.map +0 -1
- package/dist/firestore-compat.mjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/mobile.cjs.map +0 -1
- package/dist/mobile.mjs.map +0 -1
- package/dist/mocks.cjs.map +0 -1
- package/dist/mocks.mjs.map +0 -1
- package/dist/notifications.cjs.map +0 -1
- package/dist/notifications.mjs.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.mjs.map +0 -1
- package/dist/support.cjs.map +0 -1
- package/dist/support.mjs.map +0 -1
- package/dist/telemetry.cjs.map +0 -1
- package/dist/telemetry.mjs.map +0 -1
- package/dist/usage.cjs.map +0 -1
- package/dist/usage.mjs.map +0 -1
- package/dist/webhooks.cjs.map +0 -1
- package/dist/webhooks.mjs.map +0 -1
package/dist/mobile.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/errors.ts
|
|
4
|
-
var
|
|
4
|
+
var n = class t extends Error {
|
|
5
5
|
code;
|
|
6
6
|
status;
|
|
7
7
|
requestId;
|
|
@@ -14,502 +14,617 @@ var NeetruError = class _NeetruError extends Error {
|
|
|
14
14
|
* para um `NeetruDbErrorCode` mais específico (recuperável vs não).
|
|
15
15
|
*/
|
|
16
16
|
reason;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
/**
|
|
18
|
+
* 3.8.0: `x-correlation-id` da requisição que falhou. O SDK gera um UUID por
|
|
19
|
+
* chamada (ou usa o que o chamador passou) e manda no header; o Core grava o
|
|
20
|
+
* mesmo id nos logs/auditoria — cite-o ao abrir um ticket de suporte.
|
|
21
|
+
* `undefined` em erros que acontecem antes de qualquer requisição.
|
|
22
|
+
*/
|
|
23
|
+
correlationId;
|
|
24
|
+
constructor(e, o, s, i, p, m) {
|
|
25
|
+
super(o), this.name = "NeetruError", this.code = e, this.status = s, this.requestId = i, this.reason = p, this.correlationId = m, Object.setPrototypeOf(this, t.prototype);
|
|
26
|
+
}
|
|
27
|
+
}, v = class t extends n {
|
|
28
|
+
constructor(e, o, s, i, p) {
|
|
29
|
+
super("auth_required", e, s, i, o, p), this.name = "NeetruAuthRequiredError", Object.setPrototypeOf(this, t.prototype);
|
|
25
30
|
}
|
|
26
31
|
};
|
|
27
32
|
|
|
28
33
|
// src/types.ts
|
|
29
|
-
var
|
|
34
|
+
var H = "https://api.neetru.com";
|
|
30
35
|
|
|
31
36
|
// src/base-url-allowlist.ts
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
var SAFE_DEV_HOST_RE = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
|
|
36
|
-
function isSafeDevHost(hostname) {
|
|
37
|
-
return SAFE_DEV_HOST_RE.test(hostname);
|
|
37
|
+
var B = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]), le = ".neetru.com", ue = "neetru.com", de = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
|
|
38
|
+
function j(t) {
|
|
39
|
+
return de.test(t);
|
|
38
40
|
}
|
|
39
|
-
function
|
|
40
|
-
return
|
|
41
|
+
function pe(t) {
|
|
42
|
+
return t.toLowerCase().replace(/\.+$/, "");
|
|
41
43
|
}
|
|
42
|
-
function
|
|
43
|
-
if (typeof
|
|
44
|
-
throw new
|
|
45
|
-
|
|
46
|
-
let parsed;
|
|
44
|
+
function F(t, e = []) {
|
|
45
|
+
if (typeof t != "string" || t.length === 0)
|
|
46
|
+
throw new n("invalid_config", "baseUrl is required");
|
|
47
|
+
let o;
|
|
47
48
|
try {
|
|
48
|
-
|
|
49
|
+
o = new URL(t);
|
|
49
50
|
} catch {
|
|
50
|
-
throw new
|
|
51
|
-
}
|
|
52
|
-
const protocol = parsed.protocol;
|
|
53
|
-
const hostname = normalizeHostname(parsed.hostname);
|
|
54
|
-
if (isInsecureBypassActive()) {
|
|
55
|
-
if (typeof console !== "undefined") {
|
|
56
|
-
console.warn(
|
|
57
|
-
`[neetru-sdk] NEETRU_ALLOW_INSECURE_BASEURL=1 ativo. baseUrl=${baseUrl} aceito sem valida\xE7\xE3o.`
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
return baseUrl.replace(/\/+$/, "");
|
|
51
|
+
throw new n("invalid_config", `baseUrl is not a valid URL: ${t}`);
|
|
61
52
|
}
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
let s = o.protocol, i = pe(o.hostname);
|
|
54
|
+
if (fe())
|
|
55
|
+
return typeof console < "u" && console.warn(
|
|
56
|
+
`[neetru-sdk] NEETRU_ALLOW_INSECURE_BASEURL=1 ativo. baseUrl=${t} aceito sem valida\xE7\xE3o.`
|
|
57
|
+
), t.replace(/\/+$/, "");
|
|
58
|
+
if (s !== "https:" && s !== "http:")
|
|
59
|
+
throw new n(
|
|
64
60
|
"invalid_config",
|
|
65
|
-
`baseUrl protocol must be http: or https:, got ${
|
|
61
|
+
`baseUrl protocol must be http: or https:, got ${s}`
|
|
66
62
|
);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (!isLoopback) {
|
|
71
|
-
throw new NeetruError(
|
|
63
|
+
if (s === "http:") {
|
|
64
|
+
if (!(B.has(i) || j(i)))
|
|
65
|
+
throw new n(
|
|
72
66
|
"invalid_config",
|
|
73
|
-
`baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${
|
|
67
|
+
`baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${i}. Use https: or set NEETRU_ALLOW_INSECURE_BASEURL=1 to bypass.`
|
|
74
68
|
);
|
|
75
|
-
|
|
76
|
-
return baseUrl.replace(/\/+$/, "");
|
|
69
|
+
return t.replace(/\/+$/, "");
|
|
77
70
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!isNeetruDomain && !isAllowedHost && !isLoopbackHttps) {
|
|
85
|
-
throw new NeetruError(
|
|
71
|
+
let p = i === ue || i.endsWith(le), m = e.some((h) => {
|
|
72
|
+
let w = h.toLowerCase();
|
|
73
|
+
return i === w || i.endsWith(`.${w}`);
|
|
74
|
+
}), I = B.has(i) || j(i);
|
|
75
|
+
if (!p && !m && !I)
|
|
76
|
+
throw new n(
|
|
86
77
|
"invalid_config",
|
|
87
|
-
`baseUrl ${
|
|
78
|
+
`baseUrl ${i} is not in the allowlist. Allowed: *.neetru.com, localhost, or configure { allowedHosts: ['...'] }. Bypass: NEETRU_ALLOW_INSECURE_BASEURL=1.`
|
|
88
79
|
);
|
|
89
|
-
|
|
90
|
-
return baseUrl.replace(/\/+$/, "");
|
|
80
|
+
return t.replace(/\/+$/, "");
|
|
91
81
|
}
|
|
92
|
-
function
|
|
82
|
+
function fe() {
|
|
93
83
|
try {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (envVal === "1" || envVal === "true") return true;
|
|
84
|
+
let e = globalThis.process?.env?.NEETRU_ALLOW_INSECURE_BASEURL;
|
|
85
|
+
if (e === "1" || e === "true") return !0;
|
|
97
86
|
} catch {
|
|
98
87
|
}
|
|
99
88
|
try {
|
|
100
|
-
|
|
101
|
-
if (
|
|
89
|
+
let t = globalThis.NEETRU_ALLOW_INSECURE_BASEURL;
|
|
90
|
+
if (t === "1" || t === "true" || t === !0) return !0;
|
|
102
91
|
} catch {
|
|
103
92
|
}
|
|
104
93
|
return false;
|
|
105
94
|
}
|
|
106
95
|
|
|
107
96
|
// src/api-key.ts
|
|
108
|
-
var
|
|
109
|
-
function
|
|
110
|
-
if (typeof
|
|
111
|
-
throw new
|
|
97
|
+
var ge = /^nrt_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
|
|
98
|
+
function z(t) {
|
|
99
|
+
if (typeof t != "string" || t.length === 0)
|
|
100
|
+
throw new n(
|
|
112
101
|
"invalid_config",
|
|
113
102
|
"apiKey is required (formato nrt_<keyId>_<secret>)"
|
|
114
103
|
);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
throw new NeetruError(
|
|
104
|
+
let e = ge.exec(t);
|
|
105
|
+
if (!e)
|
|
106
|
+
throw new n(
|
|
119
107
|
"invalid_config",
|
|
120
108
|
"apiKey malformado - esperado formato nrt_<keyId>_<secret>"
|
|
121
109
|
);
|
|
122
|
-
}
|
|
123
|
-
return { keyId: match[1], secret: match[2] };
|
|
110
|
+
return { keyId: e[1], secret: e[2] };
|
|
124
111
|
}
|
|
125
112
|
|
|
126
113
|
// src/auth-pkce-shared.ts
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
if (!
|
|
130
|
-
throw new
|
|
114
|
+
function V() {
|
|
115
|
+
let t = globalThis.crypto;
|
|
116
|
+
if (!t || typeof t.getRandomValues != "function" || !t.subtle)
|
|
117
|
+
throw new n(
|
|
131
118
|
"runtime_unsupported",
|
|
132
119
|
"auth.signIn requer WebCrypto (crypto.subtle) \u2014 indispon\xEDvel neste runtime. Use HTTPS (ou http://localhost) num browser moderno, ou instale um polyfill WebCrypto (ex: react-native-quick-crypto) em React Native."
|
|
133
120
|
);
|
|
134
|
-
|
|
135
|
-
return c;
|
|
121
|
+
return t;
|
|
136
122
|
}
|
|
137
|
-
function
|
|
138
|
-
let
|
|
139
|
-
for (
|
|
140
|
-
|
|
141
|
-
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
123
|
+
function W(t) {
|
|
124
|
+
let e = "";
|
|
125
|
+
for (let s of t) e += String.fromCharCode(s);
|
|
126
|
+
return (typeof btoa == "function" ? btoa(e) : Buffer.from(e, "binary").toString("base64")).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
142
127
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return base64UrlFromBytes(bytes);
|
|
128
|
+
function x(t, e) {
|
|
129
|
+
let o = new Uint8Array(e);
|
|
130
|
+
return t.getRandomValues(o), W(o);
|
|
147
131
|
}
|
|
148
|
-
async function
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return base64UrlFromBytes(new Uint8Array(digest));
|
|
132
|
+
async function J(t, e) {
|
|
133
|
+
let o = new TextEncoder().encode(e), s = await t.subtle.digest("SHA-256", o);
|
|
134
|
+
return W(new Uint8Array(s));
|
|
152
135
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
155
|
-
return overrideAuthUrl ?? baseUrl.replace(/^https?:\/\/api\./, "https://auth.");
|
|
136
|
+
function S(t) {
|
|
137
|
+
return (typeof globalThis.NEETRU_AUTH_URL == "string" ? globalThis.NEETRU_AUTH_URL : null) ?? t.replace(/^https?:\/\/api\./, "https://auth.");
|
|
156
138
|
}
|
|
157
|
-
function
|
|
158
|
-
let
|
|
159
|
-
if (!
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
if (!clientId) {
|
|
163
|
-
throw new NeetruError(
|
|
139
|
+
function L(t) {
|
|
140
|
+
let e = t.oidcClientId;
|
|
141
|
+
if (!e && t.apiKey && (e = z(t.apiKey).keyId), !e)
|
|
142
|
+
throw new n(
|
|
164
143
|
"invalid_config",
|
|
165
144
|
"auth OIDC requer `oidcClientId` (ou `apiKey`) configurado para montar o client_id."
|
|
166
145
|
);
|
|
167
|
-
|
|
168
|
-
return clientId;
|
|
146
|
+
return e;
|
|
169
147
|
}
|
|
170
|
-
function
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
url.searchParams.set("client_id", params.clientId);
|
|
174
|
-
url.searchParams.set("redirect_uri", params.redirectUri);
|
|
175
|
-
url.searchParams.set("scope", params.scope);
|
|
176
|
-
url.searchParams.set("state", params.state);
|
|
177
|
-
url.searchParams.set("nonce", params.nonce);
|
|
178
|
-
url.searchParams.set("code_challenge", params.codeChallenge);
|
|
179
|
-
url.searchParams.set("code_challenge_method", "S256");
|
|
180
|
-
return url;
|
|
148
|
+
function G(t) {
|
|
149
|
+
let e = new URL("/api/v1/oauth/authorize", t.idpOrigin);
|
|
150
|
+
return e.searchParams.set("response_type", "code"), e.searchParams.set("client_id", t.clientId), e.searchParams.set("redirect_uri", t.redirectUri), e.searchParams.set("scope", t.scope), e.searchParams.set("state", t.state), e.searchParams.set("nonce", t.nonce), e.searchParams.set("code_challenge", t.codeChallenge), e.searchParams.set("code_challenge_method", "S256"), e;
|
|
181
151
|
}
|
|
182
|
-
var
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
if (
|
|
152
|
+
var X = "/api/v1/oauth/token";
|
|
153
|
+
function O(t) {
|
|
154
|
+
let e = t.split(".");
|
|
155
|
+
if (e.length !== 3) return null;
|
|
186
156
|
try {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const decoded = typeof atob === "function" ? atob(b64 + pad) : Buffer.from(b64 + pad, "base64").toString("utf-8");
|
|
190
|
-
return JSON.parse(decoded);
|
|
157
|
+
let o = e[1].replace(/-/g, "+").replace(/_/g, "/"), s = "=".repeat((4 - o.length % 4) % 4), i = typeof atob == "function" ? atob(o + s) : Buffer.from(o + s, "base64").toString("utf-8");
|
|
158
|
+
return JSON.parse(i);
|
|
191
159
|
} catch {
|
|
192
160
|
return null;
|
|
193
161
|
}
|
|
194
162
|
}
|
|
195
|
-
function
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
isStaff: payload.is_staff === true,
|
|
208
|
-
isCustomer: payload.is_customer === true,
|
|
209
|
-
tenantId: typeof payload.tenant_id === "string" ? payload.tenant_id : void 0,
|
|
210
|
-
...payload
|
|
163
|
+
function T(t) {
|
|
164
|
+
let e = O(t);
|
|
165
|
+
return !e || typeof e.sub != "string" || typeof e.exp == "number" && e.exp * 1e3 < Date.now() ? null : {
|
|
166
|
+
uid: e.sub,
|
|
167
|
+
email: typeof e.email == "string" ? e.email : "",
|
|
168
|
+
emailVerified: typeof e.email_verified == "boolean" ? e.email_verified : void 0,
|
|
169
|
+
displayName: typeof e.name == "string" ? e.name : void 0,
|
|
170
|
+
photoURL: typeof e.picture == "string" ? e.picture : void 0,
|
|
171
|
+
isStaff: e.is_staff === true,
|
|
172
|
+
isCustomer: e.is_customer === true,
|
|
173
|
+
tenantId: typeof e.tenant_id == "string" ? e.tenant_id : void 0,
|
|
174
|
+
...e
|
|
211
175
|
};
|
|
212
176
|
}
|
|
177
|
+
var me = "/api/v1/oauth/revoke";
|
|
178
|
+
async function Y(t, e, o, s) {
|
|
179
|
+
let i = `${e}${me}`, p = true;
|
|
180
|
+
for (let m of s) {
|
|
181
|
+
if (!m.token) continue;
|
|
182
|
+
let I = new URLSearchParams({
|
|
183
|
+
token: m.token,
|
|
184
|
+
token_type_hint: m.hint,
|
|
185
|
+
client_id: o
|
|
186
|
+
}).toString(), h = false;
|
|
187
|
+
for (let w = 0; w < 2 && !h; w++)
|
|
188
|
+
try {
|
|
189
|
+
if (h = (await t(i, {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
192
|
+
body: I
|
|
193
|
+
})).ok, !h) break;
|
|
194
|
+
} catch {
|
|
195
|
+
w === 0 && await new Promise((_) => setTimeout(_, 500));
|
|
196
|
+
}
|
|
197
|
+
h || (p = false);
|
|
198
|
+
}
|
|
199
|
+
return p;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/server-only-key.ts
|
|
203
|
+
function Z(t) {
|
|
204
|
+
if (!(t == null || t === ""))
|
|
205
|
+
throw new n(
|
|
206
|
+
"server_only_key",
|
|
207
|
+
"[Neetru SDK] Recusado: @neetru/sdk/mobile n\xE3o aceita apiKey. A credencial nrt_ do produto \xE9 S\xD3 DE SERVIDOR \u2014 dentro do app ela \xE9 extra\xEDvel do pacote (.apk/.ipa). Remova a apiKey (e qualquer EXPO_PUBLIC_*_KEY com ela) do app: fa\xE7a login com oidcClientId (client OIDC p\xFAblico do app) e chame a API do seu produto com o access_token do usu\xE1rio; o backend do produto usa o SDK com a chave.",
|
|
208
|
+
void 0,
|
|
209
|
+
void 0,
|
|
210
|
+
"react-native"
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// src/correlation.ts
|
|
215
|
+
var Q = "x-correlation-id";
|
|
216
|
+
var he = /^[A-Za-z0-9._:\-]+$/;
|
|
217
|
+
function ee(t) {
|
|
218
|
+
return typeof t == "string" && t.length > 0 && t.length <= 128 && he.test(t);
|
|
219
|
+
}
|
|
220
|
+
function ye() {
|
|
221
|
+
let t = globalThis.crypto;
|
|
222
|
+
try {
|
|
223
|
+
if (t && typeof t.randomUUID == "function") return t.randomUUID();
|
|
224
|
+
} catch {
|
|
225
|
+
}
|
|
226
|
+
let e = new Uint8Array(16), o = false;
|
|
227
|
+
try {
|
|
228
|
+
t && typeof t.getRandomValues == "function" && (t.getRandomValues(e), o = !0);
|
|
229
|
+
} catch {
|
|
230
|
+
o = false;
|
|
231
|
+
}
|
|
232
|
+
if (!o)
|
|
233
|
+
for (let i = 0; i < e.length; i++) e[i] = Math.floor(Math.random() * 256);
|
|
234
|
+
e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
|
|
235
|
+
let s = Array.from(e, (i) => i.toString(16).padStart(2, "0")).join("");
|
|
236
|
+
return `${s.slice(0, 8)}-${s.slice(8, 12)}-${s.slice(12, 16)}-${s.slice(16, 20)}-${s.slice(20)}`;
|
|
237
|
+
}
|
|
238
|
+
function K(t, e) {
|
|
239
|
+
let o, s = {};
|
|
240
|
+
for (let [p, m] of Object.entries(t)) {
|
|
241
|
+
if (p.toLowerCase() === Q) {
|
|
242
|
+
ee(m) && (o = m);
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
s[p] = m;
|
|
246
|
+
}
|
|
247
|
+
let i = o ?? (ee(e) ? e : void 0) ?? ye();
|
|
248
|
+
return s[Q] = i, { headers: s, correlationId: i };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/http.ts
|
|
252
|
+
function te(t) {
|
|
253
|
+
return t === 401 ? "unauthorized" : t === 403 ? "forbidden" : t === 404 ? "not_found" : t === 409 ? "conflict" : t === 410 ? "gone" : t === 422 || t === 400 ? "validation_failed" : t === 429 ? "rate_limited" : t >= 500 ? "server_error" : "unknown";
|
|
254
|
+
}
|
|
213
255
|
|
|
214
256
|
// src/mobile.ts
|
|
215
|
-
var
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
257
|
+
var k = "neetru_oauth_tx", U = "neetru_id_token", E = "neetru_refresh_token", C = "neetru_access_token", be = 3e4, we = "/api/v1/oauth/userinfo";
|
|
258
|
+
function _e(t) {
|
|
259
|
+
if (t === void 0 || t === "") return null;
|
|
260
|
+
let e;
|
|
261
|
+
try {
|
|
262
|
+
e = new URL(t);
|
|
263
|
+
} catch {
|
|
264
|
+
throw new n("invalid_config", `productApiUrl inv\xE1lida: ${t}`);
|
|
265
|
+
}
|
|
266
|
+
let o = e.hostname === "localhost" || e.hostname === "127.0.0.1";
|
|
267
|
+
if (e.protocol !== "https:" && !(e.protocol === "http:" && o))
|
|
268
|
+
throw new n(
|
|
269
|
+
"invalid_config",
|
|
270
|
+
"productApiUrl precisa ser https:// (http s\xF3 para localhost) \u2014 o access_token n\xE3o pode trafegar sem TLS."
|
|
271
|
+
);
|
|
272
|
+
return e;
|
|
273
|
+
}
|
|
274
|
+
function ke(t) {
|
|
275
|
+
if (Z(t.apiKey), !t.storage)
|
|
276
|
+
throw new n(
|
|
221
277
|
"invalid_config",
|
|
222
278
|
"createMobileAuthNamespace requer `storage` (MobileAuthStorage) \u2014 ver JSDoc de src/mobile.ts requisito 4."
|
|
223
279
|
);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
throw new NeetruError(
|
|
280
|
+
if (typeof t.openAuthUrl != "function")
|
|
281
|
+
throw new n(
|
|
227
282
|
"invalid_config",
|
|
228
283
|
"createMobileAuthNamespace requer `openAuthUrl` (browser externo, NUNCA WebView embutida) \u2014 ver JSDoc de src/mobile.ts requisito 3."
|
|
229
284
|
);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
throw new NeetruError(
|
|
285
|
+
let e = t.fetch ?? globalThis.fetch;
|
|
286
|
+
if (typeof e != "function")
|
|
287
|
+
throw new n(
|
|
234
288
|
"invalid_config",
|
|
235
289
|
"fetch is not available in this runtime. Pass `fetch` explicitly to createMobileAuthNamespace."
|
|
236
290
|
);
|
|
237
|
-
|
|
238
|
-
|
|
291
|
+
if (typeof t.oidcClientId != "string" || t.oidcClientId.length === 0)
|
|
292
|
+
throw new n(
|
|
293
|
+
"invalid_config",
|
|
294
|
+
"createMobileAuthNamespace requer `oidcClientId` \u2014 o client OIDC P\xDABLICO do app registrado no Core (a apiKey n\xE3o \xE9 aceita no app; ver requisito 6 no JSDoc de src/mobile.ts)."
|
|
295
|
+
);
|
|
296
|
+
let o = F(t.baseUrl ?? H, t.allowedHosts ?? []);
|
|
239
297
|
return {
|
|
240
|
-
fetchImpl:
|
|
241
|
-
baseUrl,
|
|
242
|
-
oidcClientId:
|
|
243
|
-
|
|
244
|
-
storage:
|
|
245
|
-
openAuthUrl:
|
|
298
|
+
fetchImpl: e.bind(globalThis),
|
|
299
|
+
baseUrl: o,
|
|
300
|
+
oidcClientId: t.oidcClientId,
|
|
301
|
+
productApiUrl: _e(t.productApiUrl),
|
|
302
|
+
storage: t.storage,
|
|
303
|
+
openAuthUrl: t.openAuthUrl
|
|
246
304
|
};
|
|
247
305
|
}
|
|
248
|
-
|
|
249
|
-
let
|
|
306
|
+
function ve(t) {
|
|
307
|
+
let o = O(t)?.exp;
|
|
308
|
+
return typeof o == "number" ? o * 1e3 : null;
|
|
309
|
+
}
|
|
310
|
+
async function re(t, e, o) {
|
|
311
|
+
let s;
|
|
250
312
|
try {
|
|
251
|
-
|
|
313
|
+
s = await t(e, {
|
|
252
314
|
method: "POST",
|
|
253
315
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
254
|
-
body:
|
|
316
|
+
body: o.toString()
|
|
255
317
|
});
|
|
256
|
-
} catch (
|
|
257
|
-
throw new
|
|
318
|
+
} catch (p) {
|
|
319
|
+
throw new n(
|
|
258
320
|
"network_error",
|
|
259
|
-
`POST ${
|
|
321
|
+
`POST ${e} falhou (network): ${p?.message ?? String(p)}`
|
|
260
322
|
);
|
|
261
323
|
}
|
|
262
|
-
let
|
|
324
|
+
let i = null;
|
|
263
325
|
try {
|
|
264
|
-
|
|
326
|
+
i = await s.json();
|
|
265
327
|
} catch {
|
|
266
|
-
|
|
328
|
+
i = null;
|
|
267
329
|
}
|
|
268
|
-
if (!
|
|
269
|
-
|
|
270
|
-
throw new
|
|
330
|
+
if (!s.ok || typeof i?.error == "string") {
|
|
331
|
+
let p = typeof i?.error_description == "string" && i.error_description || typeof i?.error == "string" && i.error || `HTTP ${s.status}`;
|
|
332
|
+
throw new n(
|
|
271
333
|
"token_exchange_failed",
|
|
272
|
-
`Troca de tokens falhou no /token: ${
|
|
273
|
-
|
|
334
|
+
`Troca de tokens falhou no /token: ${p}`,
|
|
335
|
+
s.status
|
|
274
336
|
);
|
|
275
337
|
}
|
|
276
|
-
return
|
|
338
|
+
return i ?? {};
|
|
277
339
|
}
|
|
278
|
-
function
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
return `${resolveIdpOrigin(resolved.baseUrl)}${OAUTH_TOKEN_PATH}`;
|
|
340
|
+
function je(t) {
|
|
341
|
+
let e = ke(t), o = /* @__PURE__ */ new Set();
|
|
342
|
+
function s() {
|
|
343
|
+
return `${S(e.baseUrl)}${X}`;
|
|
283
344
|
}
|
|
284
|
-
async function
|
|
285
|
-
|
|
286
|
-
for (
|
|
345
|
+
async function i() {
|
|
346
|
+
let r = await h();
|
|
347
|
+
for (let a of o)
|
|
287
348
|
try {
|
|
288
|
-
|
|
349
|
+
a(r);
|
|
289
350
|
} catch {
|
|
290
351
|
}
|
|
291
|
-
}
|
|
292
352
|
}
|
|
293
|
-
async function
|
|
294
|
-
if (!
|
|
295
|
-
throw new
|
|
353
|
+
async function p(r) {
|
|
354
|
+
if (!r?.redirectUri)
|
|
355
|
+
throw new n(
|
|
296
356
|
"invalid_config",
|
|
297
357
|
"mobile auth.signIn requer `redirectUri` (Universal Link/App Link https://... registrado no Core) \u2014 n\xE3o h\xE1 location.origin impl\xEDcito em React Native."
|
|
298
358
|
);
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const codeVerifier = randomUrlSafe(crypto, 32);
|
|
306
|
-
const codeChallenge = await pkceChallengeS256(crypto, codeVerifier);
|
|
307
|
-
const tx = {
|
|
308
|
-
state,
|
|
309
|
-
nonce,
|
|
310
|
-
codeVerifier,
|
|
311
|
-
redirectUri: options.redirectUri,
|
|
312
|
-
postLoginRedirect: options.postLoginRedirect
|
|
359
|
+
let a = V(), c = r.scope ?? "openid profile email", l = L(e), d = x(a, 16), u = x(a, 16), f = x(a, 32), g = await J(a, f), y = {
|
|
360
|
+
state: d,
|
|
361
|
+
nonce: u,
|
|
362
|
+
codeVerifier: f,
|
|
363
|
+
redirectUri: r.redirectUri,
|
|
364
|
+
postLoginRedirect: r.postLoginRedirect
|
|
313
365
|
};
|
|
314
|
-
await
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
codeChallenge
|
|
366
|
+
await e.storage.setItem(k, JSON.stringify(y));
|
|
367
|
+
let b = S(e.baseUrl), R = G({
|
|
368
|
+
idpOrigin: b,
|
|
369
|
+
clientId: l,
|
|
370
|
+
redirectUri: r.redirectUri,
|
|
371
|
+
scope: c,
|
|
372
|
+
state: d,
|
|
373
|
+
nonce: u,
|
|
374
|
+
codeChallenge: g
|
|
324
375
|
});
|
|
325
|
-
await
|
|
376
|
+
await e.openAuthUrl(R.toString());
|
|
326
377
|
}
|
|
327
|
-
async function
|
|
328
|
-
if (!
|
|
329
|
-
throw new
|
|
378
|
+
async function m(r) {
|
|
379
|
+
if (!r || typeof r != "string")
|
|
380
|
+
throw new n(
|
|
330
381
|
"invalid_config",
|
|
331
382
|
"mobile auth.completeSignIn requer `callbackUrl` (a URL completa do deep link de retorno) \u2014 mobile n\xE3o tem location.href impl\xEDcito."
|
|
332
383
|
);
|
|
333
|
-
|
|
334
|
-
let parsed;
|
|
384
|
+
let a;
|
|
335
385
|
try {
|
|
336
|
-
|
|
386
|
+
a = new URL(r);
|
|
337
387
|
} catch {
|
|
338
|
-
throw new
|
|
388
|
+
throw new n("invalid_config", `callbackUrl n\xE3o \xE9 uma URL v\xE1lida: ${r}`);
|
|
339
389
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
await resolved.storage.removeItem(OIDC_TX_KEY);
|
|
345
|
-
throw new NeetruError(idpError, `OIDC authorize falhou: ${desc}`);
|
|
390
|
+
let c = a.searchParams, l = c.get("error");
|
|
391
|
+
if (l) {
|
|
392
|
+
let ce = c.get("error_description") ?? l;
|
|
393
|
+
throw await e.storage.removeItem(k), new n(l, `OIDC authorize falhou: ${ce}`);
|
|
346
394
|
}
|
|
347
|
-
|
|
348
|
-
if (!
|
|
349
|
-
await
|
|
350
|
-
throw new NeetruError(
|
|
395
|
+
let d = c.get("code");
|
|
396
|
+
if (!d)
|
|
397
|
+
throw await e.storage.removeItem(k), new n(
|
|
351
398
|
"invalid_config",
|
|
352
399
|
"callbackUrl n\xE3o cont\xE9m `?code=` nem `?error=` \u2014 n\xE3o \xE9 um callback OIDC v\xE1lido."
|
|
353
400
|
);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const txRaw = await resolved.storage.getItem(OIDC_TX_KEY);
|
|
357
|
-
let tx = null;
|
|
358
|
-
if (txRaw) {
|
|
401
|
+
let u = c.get("state"), f = await e.storage.getItem(k), g = null;
|
|
402
|
+
if (f)
|
|
359
403
|
try {
|
|
360
|
-
|
|
404
|
+
g = JSON.parse(f);
|
|
361
405
|
} catch {
|
|
362
|
-
|
|
406
|
+
g = null;
|
|
363
407
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
throw new NeetruError(
|
|
408
|
+
if (!g)
|
|
409
|
+
throw new n(
|
|
367
410
|
"oidc_state_mismatch",
|
|
368
411
|
"Callback OIDC sem transa\xE7\xE3o pendente \u2014 `signIn` n\xE3o foi iniciado (ou j\xE1 consumido)."
|
|
369
412
|
);
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
await resolved.storage.removeItem(OIDC_TX_KEY);
|
|
373
|
-
throw new NeetruError(
|
|
413
|
+
if (!u || u !== g.state)
|
|
414
|
+
throw await e.storage.removeItem(k), new n(
|
|
374
415
|
"oidc_state_mismatch",
|
|
375
416
|
"state do callback OIDC n\xE3o confere com o da transa\xE7\xE3o (poss\xEDvel CSRF)."
|
|
376
417
|
);
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const clientId = resolveOidcClientId(resolved);
|
|
380
|
-
const form = new URLSearchParams({
|
|
418
|
+
await e.storage.removeItem(k);
|
|
419
|
+
let y = L(e), b = new URLSearchParams({
|
|
381
420
|
grant_type: "authorization_code",
|
|
382
|
-
code,
|
|
383
|
-
redirect_uri:
|
|
384
|
-
client_id:
|
|
385
|
-
code_verifier:
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
if (typeof idToken !== "string" || idToken.length === 0) {
|
|
390
|
-
throw new NeetruError(
|
|
421
|
+
code: d,
|
|
422
|
+
redirect_uri: g.redirectUri,
|
|
423
|
+
client_id: y,
|
|
424
|
+
code_verifier: g.codeVerifier
|
|
425
|
+
}), R = await re(e.fetchImpl, s(), b), A = R.id_token;
|
|
426
|
+
if (typeof A != "string" || A.length === 0)
|
|
427
|
+
throw new n(
|
|
391
428
|
"token_exchange_failed",
|
|
392
429
|
"Resposta do /token sem `id_token` \u2014 o login n\xE3o pode ser completado."
|
|
393
430
|
);
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
throw new NeetruError(
|
|
431
|
+
let $ = O(A);
|
|
432
|
+
if (!$)
|
|
433
|
+
throw new n(
|
|
398
434
|
"token_exchange_failed",
|
|
399
435
|
"id_token retornado pelo /token \xE9 malformado (payload indecodific\xE1vel)."
|
|
400
436
|
);
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
throw new NeetruError(
|
|
437
|
+
if ($.nonce !== g.nonce)
|
|
438
|
+
throw new n(
|
|
404
439
|
"oidc_nonce_mismatch",
|
|
405
440
|
"nonce do id_token n\xE3o confere com o da transa\xE7\xE3o OIDC (poss\xEDvel replay). Token descartado."
|
|
406
441
|
);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
throw new NeetruError(
|
|
442
|
+
let q = T(A);
|
|
443
|
+
if (!q)
|
|
444
|
+
throw new n(
|
|
411
445
|
"token_exchange_failed",
|
|
412
446
|
"id_token retornado pelo /token n\xE3o tem `sub` ou j\xE1 est\xE1 expirado."
|
|
413
447
|
);
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
return { user, postLoginRedirect: tx.postLoginRedirect };
|
|
448
|
+
await e.storage.setItem(U, A);
|
|
449
|
+
let M = R.refresh_token;
|
|
450
|
+
return typeof M == "string" && M.length > 0 && await e.storage.setItem(E, M), await w(R.access_token), await i(), { user: q, postLoginRedirect: g.postLoginRedirect };
|
|
451
|
+
}
|
|
452
|
+
async function I() {
|
|
453
|
+
let r = await e.storage.getItem(U);
|
|
454
|
+
return r && T(r) ? r : null;
|
|
422
455
|
}
|
|
423
|
-
async function
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
return jwtToNeetruUser(token) ? token : null;
|
|
456
|
+
async function h() {
|
|
457
|
+
let r = await e.storage.getItem(U);
|
|
458
|
+
return r ? T(r) : null;
|
|
427
459
|
}
|
|
428
|
-
async function
|
|
429
|
-
|
|
430
|
-
if (!token) return null;
|
|
431
|
-
return jwtToNeetruUser(token);
|
|
460
|
+
async function w(r) {
|
|
461
|
+
typeof r == "string" && r.length > 0 ? await e.storage.setItem(C, r) : await e.storage.removeItem(C);
|
|
432
462
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
463
|
+
let _ = null;
|
|
464
|
+
function N() {
|
|
465
|
+
return _ || (_ = ne().finally(() => {
|
|
466
|
+
_ = null;
|
|
467
|
+
}), _);
|
|
468
|
+
}
|
|
469
|
+
async function ne() {
|
|
470
|
+
let r = await e.storage.getItem(E);
|
|
471
|
+
if (!r) return false;
|
|
472
|
+
let a;
|
|
437
473
|
try {
|
|
438
|
-
|
|
474
|
+
a = L(e);
|
|
439
475
|
} catch {
|
|
440
476
|
return false;
|
|
441
477
|
}
|
|
442
|
-
|
|
478
|
+
let c = new URLSearchParams({
|
|
443
479
|
grant_type: "refresh_token",
|
|
444
|
-
refresh_token:
|
|
445
|
-
client_id:
|
|
446
|
-
});
|
|
447
|
-
let payload;
|
|
480
|
+
refresh_token: r,
|
|
481
|
+
client_id: a
|
|
482
|
+
}), l;
|
|
448
483
|
try {
|
|
449
|
-
|
|
484
|
+
l = await re(e.fetchImpl, s(), c);
|
|
450
485
|
} catch {
|
|
451
486
|
return false;
|
|
452
487
|
}
|
|
453
|
-
|
|
454
|
-
if (typeof
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
await
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
488
|
+
let d = l.id_token;
|
|
489
|
+
if (typeof d != "string" || d.length === 0 || !T(d)) return false;
|
|
490
|
+
await e.storage.setItem(U, d);
|
|
491
|
+
let f = l.refresh_token;
|
|
492
|
+
return typeof f == "string" && f.length > 0 && await e.storage.setItem(E, f), await w(l.access_token), await i(), true;
|
|
493
|
+
}
|
|
494
|
+
async function P() {
|
|
495
|
+
let r = await e.storage.getItem(C);
|
|
496
|
+
if (!r) return null;
|
|
497
|
+
let a = ve(r);
|
|
498
|
+
return a === null || a - be <= Date.now() ? null : r;
|
|
499
|
+
}
|
|
500
|
+
async function D() {
|
|
501
|
+
let r = await P();
|
|
502
|
+
return r || (await N() ? P() : null);
|
|
503
|
+
}
|
|
504
|
+
async function oe() {
|
|
505
|
+
let r = `${S(e.baseUrl)}${we}`, a = async (f) => {
|
|
506
|
+
let { headers: g, correlationId: y } = K({
|
|
507
|
+
accept: "application/json",
|
|
508
|
+
authorization: `Bearer ${f}`
|
|
509
|
+
});
|
|
510
|
+
try {
|
|
511
|
+
return { res: await e.fetchImpl(r, { method: "GET", headers: g }), correlationId: y };
|
|
512
|
+
} catch (b) {
|
|
513
|
+
throw new n(
|
|
514
|
+
"network_error",
|
|
515
|
+
`GET ${r} falhou (network): ${b?.message ?? String(b)}`,
|
|
516
|
+
void 0,
|
|
517
|
+
void 0,
|
|
518
|
+
void 0,
|
|
519
|
+
y
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
}, c = await D();
|
|
523
|
+
if (!c)
|
|
524
|
+
throw new v(
|
|
525
|
+
"Sem sess\xE3o: fa\xE7a login (auth.signIn) antes de consultar o userinfo.",
|
|
526
|
+
"no_signed_in_user"
|
|
527
|
+
);
|
|
528
|
+
let { res: l, correlationId: d } = await a(c);
|
|
529
|
+
if (l.status === 401 && await N() && (c = await P(), c && ({ res: l, correlationId: d } = await a(c))), l.status === 401)
|
|
530
|
+
throw new v(
|
|
531
|
+
"O Core recusou a sess\xE3o (token revogado/expirado ou usu\xE1rio inativo). Fa\xE7a login novamente.",
|
|
532
|
+
"invalid_access_token",
|
|
533
|
+
401,
|
|
534
|
+
void 0,
|
|
535
|
+
d
|
|
536
|
+
);
|
|
537
|
+
let u;
|
|
538
|
+
try {
|
|
539
|
+
u = await l.json();
|
|
540
|
+
} catch {
|
|
541
|
+
u = void 0;
|
|
542
|
+
}
|
|
543
|
+
if (!l.ok) {
|
|
544
|
+
let f = u && typeof u == "object" && typeof u.error_description == "string" ? u.error_description : `HTTP ${l.status}`;
|
|
545
|
+
throw new n(te(l.status), `userinfo falhou: ${f}`, l.status, void 0, void 0, d);
|
|
461
546
|
}
|
|
462
|
-
|
|
463
|
-
|
|
547
|
+
if (!u || typeof u != "object" || typeof u.sub != "string")
|
|
548
|
+
throw new n("invalid_response", "userinfo sem `sub`.", l.status, void 0, void 0, d);
|
|
549
|
+
return u;
|
|
464
550
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
551
|
+
function ie(r) {
|
|
552
|
+
let a = e.productApiUrl;
|
|
553
|
+
if (!a)
|
|
554
|
+
throw new n(
|
|
555
|
+
"invalid_config",
|
|
556
|
+
"auth.authFetch requer `productApiUrl` (URL da API do seu produto) no createMobileAuthNamespace."
|
|
557
|
+
);
|
|
558
|
+
let c;
|
|
559
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(r))
|
|
472
560
|
try {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
body: JSON.stringify({ token: storedToken })
|
|
477
|
-
});
|
|
478
|
-
} catch (err) {
|
|
479
|
-
if (typeof console !== "undefined") {
|
|
480
|
-
console.warn(
|
|
481
|
-
"[neetru-sdk] mobile signOut: server-side revoke falhou. Refresh token pode estar stale.",
|
|
482
|
-
err
|
|
483
|
-
);
|
|
484
|
-
}
|
|
561
|
+
c = new URL(r);
|
|
562
|
+
} catch {
|
|
563
|
+
throw new n("invalid_config", `URL inv\xE1lida: ${r}`);
|
|
485
564
|
}
|
|
565
|
+
else {
|
|
566
|
+
let l = a.pathname.replace(/\/+$/, ""), d = r.startsWith("/") ? r : `/${r}`;
|
|
567
|
+
c = new URL(`${a.origin}${l}${d}`);
|
|
486
568
|
}
|
|
487
|
-
|
|
569
|
+
if (c.origin !== a.origin)
|
|
570
|
+
throw new n(
|
|
571
|
+
"invalid_config",
|
|
572
|
+
`auth.authFetch s\xF3 envia o access_token para a API do produto (${a.origin}); recusado: ${c.origin}.`
|
|
573
|
+
);
|
|
574
|
+
return c.toString();
|
|
575
|
+
}
|
|
576
|
+
async function se(r, a = {}) {
|
|
577
|
+
let c = ie(r), l = {};
|
|
578
|
+
new Headers(a.headers ?? {}).forEach((y, b) => {
|
|
579
|
+
l[b] = y;
|
|
580
|
+
});
|
|
581
|
+
let d = (y) => {
|
|
582
|
+
let { headers: b } = K({ ...l, authorization: `Bearer ${y}` });
|
|
583
|
+
return e.fetchImpl(c, { ...a, headers: b });
|
|
584
|
+
}, u = await D();
|
|
585
|
+
if (!u)
|
|
586
|
+
throw new v(
|
|
587
|
+
"Sem sess\xE3o: fa\xE7a login (auth.signIn) antes de chamar a API do produto.",
|
|
588
|
+
"no_signed_in_user"
|
|
589
|
+
);
|
|
590
|
+
let f = await d(u), g = a.body === void 0 || a.body === null || typeof a.body == "string";
|
|
591
|
+
return f.status === 401 && g && await N() && (u = await P(), u && (f = await d(u))), f;
|
|
592
|
+
}
|
|
593
|
+
async function ae() {
|
|
594
|
+
let r = await e.storage.getItem(E), a = await e.storage.getItem(C);
|
|
595
|
+
await e.storage.removeItem(U), await e.storage.removeItem(E), await e.storage.removeItem(C), await e.storage.removeItem(k);
|
|
596
|
+
let c = [];
|
|
597
|
+
r && c.push({ token: r, hint: "refresh_token" }), a && c.push({ token: a, hint: "access_token" }), c.length > 0 && !await Y(
|
|
598
|
+
e.fetchImpl,
|
|
599
|
+
S(e.baseUrl),
|
|
600
|
+
e.oidcClientId,
|
|
601
|
+
c
|
|
602
|
+
) && typeof console < "u" && console.warn(
|
|
603
|
+
"[neetru-sdk] mobile signOut: a revoga\xE7\xE3o no servidor n\xE3o foi confirmada. A sess\xE3o local foi encerrada, mas o refresh_token pode seguir v\xE1lido at\xE9 expirar."
|
|
604
|
+
), await i();
|
|
488
605
|
}
|
|
489
606
|
return {
|
|
490
|
-
signIn,
|
|
491
|
-
completeSignIn,
|
|
492
|
-
getIdToken,
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
607
|
+
signIn: p,
|
|
608
|
+
completeSignIn: m,
|
|
609
|
+
getIdToken: I,
|
|
610
|
+
getAccessToken: D,
|
|
611
|
+
getUserInfo: oe,
|
|
612
|
+
authFetch: se,
|
|
613
|
+
getUser: h,
|
|
614
|
+
onAuthStateChanged(r) {
|
|
615
|
+
return o.add(r), h().then((a) => {
|
|
616
|
+
if (o.has(r))
|
|
498
617
|
try {
|
|
499
|
-
|
|
618
|
+
r(a);
|
|
500
619
|
} catch {
|
|
501
620
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
return () => {
|
|
505
|
-
listeners.delete(listener);
|
|
621
|
+
}), () => {
|
|
622
|
+
o.delete(r);
|
|
506
623
|
};
|
|
507
624
|
},
|
|
508
|
-
refreshTokens,
|
|
509
|
-
signOut
|
|
625
|
+
refreshTokens: N,
|
|
626
|
+
signOut: ae
|
|
510
627
|
};
|
|
511
628
|
}
|
|
512
629
|
|
|
513
|
-
exports.createMobileAuthNamespace =
|
|
514
|
-
//# sourceMappingURL=mobile.cjs.map
|
|
515
|
-
//# sourceMappingURL=mobile.cjs.map
|
|
630
|
+
exports.createMobileAuthNamespace = je;
|