@punch-in/strapi-admin 1.2.10 → 1.2.12
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/admin/src/app.js +21 -15
- package/controllers/authentication.js +0 -8
- package/package.json +1 -1
package/admin/src/app.js
CHANGED
|
@@ -55,19 +55,24 @@ import history from './utils/history';
|
|
|
55
55
|
|
|
56
56
|
import plugins from './plugins';
|
|
57
57
|
|
|
58
|
-
// Retry on
|
|
59
|
-
// a concurrent cold-start race (multiple containers
|
|
60
|
-
// SQLite file - SQLITE_BUSY) where the Lambda
|
|
61
|
-
//
|
|
62
|
-
//
|
|
58
|
+
// Retry on a gateway error (502/503/504): the tenant Lambda backends
|
|
59
|
+
// occasionally hit a concurrent cold-start race (multiple containers
|
|
60
|
+
// contending for the same SQLite file - SQLITE_BUSY) where the Lambda
|
|
61
|
+
// crashes before doing any work at all - API Gateway surfaces that as a 502
|
|
62
|
+
// (Lambda invocation error) if it fails fast, or a 504 (its own 29s
|
|
63
|
+
// integration timeout) if the crash comes after that. Either way it's almost
|
|
64
|
+
// always transient - a follow-up request a few seconds later succeeds once
|
|
65
|
+
// one container wins. 503 is included too as the generic "backend
|
|
66
|
+
// unavailable" gateway code, though not otherwise observed here.
|
|
63
67
|
//
|
|
64
|
-
// Also retries on a *rejected* fetch, not just a resolved
|
|
65
|
-
// own gateway-generated error responses (
|
|
66
|
-
// never reach Strapi, so its CORS
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
// the
|
|
70
|
-
//
|
|
68
|
+
// Also retries on a *rejected* fetch, not just a resolved gateway-error
|
|
69
|
+
// status: API Gateway's own gateway-generated error responses (these same
|
|
70
|
+
// 502/503/504, plus throttles etc.) never reach Strapi, so its CORS
|
|
71
|
+
// middleware never adds the usual headers - the browser then discards the
|
|
72
|
+
// cross-origin response as a CORS failure and fetch() rejects instead of
|
|
73
|
+
// resolving with the status code, invisible to the `GATEWAY_ERROR_STATUSES`
|
|
74
|
+
// check below. (The per-tenant CloudFormation template's
|
|
75
|
+
// GatewayResponseDefault4xx/5xx now add a CORS header to those
|
|
71
76
|
// gateway-generated responses too, so this should mostly stop happening -
|
|
72
77
|
// this is a second, independent safety net for whatever slips through, e.g.
|
|
73
78
|
// a genuinely dropped connection that never got any response to add headers
|
|
@@ -80,13 +85,14 @@ import plugins from './plugins';
|
|
|
80
85
|
// request() call (and any other direct fetch caller) with zero changes to
|
|
81
86
|
// strapi-helper-plugin or any of its hundreds of call sites.
|
|
82
87
|
//
|
|
83
|
-
// Note: this retries every method, including POST/PUT/DELETE. A
|
|
84
|
-
// rejected fetch) here has only ever been observed as "the Lambda crashed
|
|
88
|
+
// Note: this retries every method, including POST/PUT/DELETE. A gateway
|
|
89
|
+
// error (or a rejected fetch) here has only ever been observed as "the Lambda crashed
|
|
85
90
|
// before it did anything" (see above), not "the write succeeded but the
|
|
86
91
|
// response was lost" - but that's this app's specific failure mode, not a
|
|
87
92
|
// general guarantee, so it's worth knowing if this ever gets reused
|
|
88
93
|
// somewhere with different backend behavior.
|
|
89
94
|
const RETRY_DELAYS_MS = [2000, 4000, 8000];
|
|
95
|
+
const GATEWAY_ERROR_STATUSES = [502, 503, 504];
|
|
90
96
|
const nativeFetch = window.fetch.bind(window);
|
|
91
97
|
|
|
92
98
|
const attemptFetch = (...args) =>
|
|
@@ -100,7 +106,7 @@ window.fetch = async (...args) => {
|
|
|
100
106
|
|
|
101
107
|
for (
|
|
102
108
|
let i = 0;
|
|
103
|
-
(error || response.status
|
|
109
|
+
(error || GATEWAY_ERROR_STATUSES.includes(response.status)) && i < RETRY_DELAYS_MS.length;
|
|
104
110
|
i += 1
|
|
105
111
|
) {
|
|
106
112
|
await new Promise(resolve => setTimeout(resolve, RETRY_DELAYS_MS[i]));
|
|
@@ -239,14 +239,6 @@ module.exports = {
|
|
|
239
239
|
// time compare). Read-only: an unmatched or inactive email is rejected,
|
|
240
240
|
// never used to create or activate an admin account.
|
|
241
241
|
async ssoVerify(ctx) {
|
|
242
|
-
// TEMPORARY diagnostic - ssoVerify is returning a bare 403 "Forbidden"
|
|
243
|
-
// (matching isAuthenticatedAdmin's unmessaged strapi.errors.forbidden())
|
|
244
|
-
// in production on every tenant tested, even with a correct X-Sync-Secret,
|
|
245
|
-
// despite this route's routes.json entry having no policies that could
|
|
246
|
-
// produce that. This line proves whether the request even reaches this
|
|
247
|
-
// controller at all - remove once root-caused.
|
|
248
|
-
console.log('[ssoVerify] reached controller, headers:', JSON.stringify(ctx.request.header));
|
|
249
|
-
|
|
250
242
|
const expected = process.env.SYNC_SECRET;
|
|
251
243
|
if (!expected) {
|
|
252
244
|
return ctx.internalServerError('SYNC_SECRET is not configured on this Strapi instance');
|
package/package.json
CHANGED