@jcoder-stack/abp-react 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/dist/proxy.js +42 -3
  2. package/package.json +1 -1
package/dist/proxy.js CHANGED
@@ -141,6 +141,43 @@ function resolveAbpAuthEnv(env, opts = {}) {
141
141
  });
142
142
  }
143
143
 
144
+ // src/proxy/tls-trust.ts
145
+ var TRUST_FAILURE_CODES = /* @__PURE__ */ new Set([
146
+ "CERT_HAS_EXPIRED",
147
+ "CERT_NOT_YET_VALID",
148
+ "CERT_UNTRUSTED",
149
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
150
+ "ERR_TLS_CERT_ALTNAME_INVALID",
151
+ "SELF_SIGNED_CERT_IN_CHAIN",
152
+ "UNABLE_TO_GET_ISSUER_CERT",
153
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
154
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE"
155
+ ]);
156
+ var MAX_DEPTH = 5;
157
+ function property(value, key) {
158
+ if (typeof value !== "object" || value === null) return void 0;
159
+ return value[key];
160
+ }
161
+ function search(value, depth) {
162
+ if (depth > MAX_DEPTH || typeof value !== "object" || value === null) return null;
163
+ const code = property(value, "code");
164
+ if (typeof code === "string" && TRUST_FAILURE_CODES.has(code)) return code;
165
+ const aggregated = property(value, "errors");
166
+ if (Array.isArray(aggregated)) {
167
+ for (const inner of aggregated) {
168
+ const found = search(inner, depth + 1);
169
+ if (found !== null) return found;
170
+ }
171
+ }
172
+ return search(property(value, "cause"), depth + 1);
173
+ }
174
+ function tlsTrustFailureCode(error) {
175
+ return search(error, 0);
176
+ }
177
+ function tlsTrustFailureMessage(code, url) {
178
+ return `abp proxy: upstream TLS certificate is not trusted (${code}) at ${new URL(url).origin}. Node verifies against its own CA list and ignores the OS keychain, so a self-signed dev certificate the browser accepts still fails here. Start the server with NODE_EXTRA_CA_CERTS=<pem path>; it is read at startup, so putting it in .env has no effect.`;
179
+ }
180
+
144
181
  // src/proxy/proxy.ts
145
182
  var AbpProxyError = class extends Error {
146
183
  constructor(message, setCookies, opts) {
@@ -235,16 +272,18 @@ function createAbpProxy(opts) {
235
272
  signal: AbortSignal.any([...stops, AbortSignal.timeout(timeoutMs)])
236
273
  });
237
274
  } catch (error) {
238
- if (attempt < maxRetries && !stopped()) {
275
+ const tlsCode = tlsTrustFailureCode(error);
276
+ if (tlsCode === null && attempt < maxRetries && !stopped()) {
239
277
  opts.logger?.debug("proxy retry after network error", { attempt, path: req.path });
240
278
  if (await backoff()) continue;
241
279
  }
280
+ const failure = tlsCode === null ? error : new Error(tlsTrustFailureMessage(tlsCode, url), { cause: error });
242
281
  if (setCookies.length > 0) {
243
282
  throw new AbpProxyError("abp proxy request failed after refresh", setCookies, {
244
- cause: error
283
+ cause: failure
245
284
  });
246
285
  }
247
- throw error;
286
+ throw failure;
248
287
  }
249
288
  if (res.status === 401 && !refreshedOnce && session?.tokens.refreshToken !== void 0) {
250
289
  refreshedOnce = true;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jcoder-stack/abp-react",
3
3
  "description": "纯 React ABP 前端框架运行时:日志、ABP 类型与 zod 解析、fetch client、认证会话、ABP 代理网关、权限、i18n、React Provider/hooks、TanStack Router 守卫;按子路径分域导出",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {