@mindful-web/marko-web-identity-x 1.80.0 → 1.80.2
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/CLAUDE.md +37 -2
- package/components/access.marko.js +2 -2
- package/components/comment-stream.marko.js +2 -2
- package/components/context.marko.js +2 -2
- package/components/form-access.marko.js +2 -2
- package/components/form-authenticate.marko.js +2 -2
- package/components/form-change-email.marko.js +2 -2
- package/components/form-login.marko.js +2 -2
- package/components/form-logout.marko.js +2 -2
- package/components/form-profile.marko.js +2 -2
- package/components/form-register.marko.js +2 -2
- package/components/google-init.marko.js +2 -2
- package/components/google-sign-in-button.marko.js +2 -2
- package/components/identify.marko.js +2 -2
- package/components/non-auth-identify.marko.js +2 -2
- package/components/subscribe.marko.js +2 -2
- package/package.json +5 -5
- package/routes/google.js +67 -4
package/CLAUDE.md
CHANGED
|
@@ -94,7 +94,21 @@ segment — a trace is the only place a call still *in flight* when its transact
|
|
|
94
94
|
record. Same treatment on the Omeda client in `marko-web-omeda/middleware/graphql-client.js`
|
|
95
95
|
(20s, `OMEDA_REQUEST_TIMEOUT_MS`), which had the identical no-timeout defect and sits on the blocking
|
|
96
96
|
path of authentication. To compare upstreams:
|
|
97
|
-
`SELECT
|
|
97
|
+
`SELECT sum(sampleRate) FROM MindfulApiCall FACET api, operation`.
|
|
98
|
+
|
|
99
|
+
**`MindfulApiCall` is sampled.** Unsampled it ran ~55k events/hour / ~40M per month on the Fusable
|
|
100
|
+
fleet, 88.9% of it `GetActiveAppContext` + `CheckContentAccess` — per-page-load context calls that
|
|
101
|
+
are uniformly fast and analytically useless. Kept: **every non-`ok` outcome**, **every `ok` call
|
|
102
|
+
>= `MINDFUL_API_CALL_SLOW_MS`** (default 250ms — deliberately under Omeda's observed p95 of 282ms, so
|
|
103
|
+
ordinary Omeda latency stays visible while fast idx calls fall away), and **1 in
|
|
104
|
+
`MINDFUL_API_CALL_SAMPLE_RATE`** (default 100) of the rest. Each event carries `sampleRate` = the
|
|
105
|
+
number of real calls it represents, so `sum(sampleRate)` recovers true volume; `sampleRate = 1` means
|
|
106
|
+
the call was kept because it failed or was slow.
|
|
107
|
+
|
|
108
|
+
Consequences when querying: `average(ms)` over everything **skews high** (fast calls are
|
|
109
|
+
under-represented by design) — filter `WHERE sampleRate = 1` for the error/slow tail, or
|
|
110
|
+
`WHERE sampleRate > 1` for a fast-call view. Set `MINDFUL_API_CALL_SAMPLE_RATE=1` to record
|
|
111
|
+
everything again during an investigation, no deploy required.
|
|
98
112
|
|
|
99
113
|
It wraps `client.query`/`client.mutate`, **not** `fetch` — `@parameter1/omeda-graphql-client` sets
|
|
100
114
|
`fetch` *after* spreading the caller's `linkConfig`, so a wrapped transport cannot be injected from
|
|
@@ -150,6 +164,26 @@ so it bails, writes no `autoSignups`, and **no `subscribe` conversion is ever re
|
|
|
150
164
|
`idxAutoSignupCount: 0` seen on every completed One Tap sign-in on overdriveonline.com. Safe to await
|
|
151
165
|
only because the Omeda client now has a request timeout.
|
|
152
166
|
|
|
167
|
+
**The name backfill is non-fatal, and must stay that way.** `GoogleSignInUpdateUser`
|
|
168
|
+
(`updateOwnAppUser`) is the **only** call in this route authenticated as the *user* rather than the
|
|
169
|
+
org — every other one passes `context: { apiToken: getOrgUserApiToken() }` — so it is the only one
|
|
170
|
+
depending on the session token minted moments earlier already being readable. Production shows it
|
|
171
|
+
returning *"The provided value is not a valid token"*, while the same token value works on the very
|
|
172
|
+
next request arriving from the cookie: a read-after-write race on the idx token store. Retried once
|
|
173
|
+
for that reason.
|
|
174
|
+
|
|
175
|
+
Non-fatal matters more than the retry. It backfills a first and last name — cosmetic — but
|
|
176
|
+
`tokenCookie.setTo` has **already run**, so the user is authenticated by the time it executes.
|
|
177
|
+
Throwing turned a fully successful sign-in into a 500, and the client, seeing `!data.ok`, ran `fail()`
|
|
178
|
+
and redirected a *logged-in* user to `/user/login`. A missing display name must never cost someone
|
|
179
|
+
their session. Failures report through `onHookError` and the route continues.
|
|
180
|
+
|
|
181
|
+
`FACET idxNameBackfill` (`ok` | `retried` | `failed`) distinguishes the two bugs that share this one
|
|
182
|
+
error message: if `retried` dominates it is the race; if `failed` dominates the impersonation token
|
|
183
|
+
simply cannot authorize this mutation, and the fix is to stop using it — backfill before impersonation
|
|
184
|
+
via `setUnverifiedAppUserData` (org-token, but writes *unverified* data, so it is a semantic change
|
|
185
|
+
worth deciding deliberately).
|
|
186
|
+
|
|
153
187
|
`idxGoogleStepMs` records elapsed ms at the start of each step, making the route self-profiling:
|
|
154
188
|
`FACET idxGoogleStep SELECT max(idxGoogleStepMs)` shows where the ~12s on a *successful* sign-in
|
|
155
189
|
goes, and a request that dies mid-flight still reports how far it got. Responds `{ ok, requiresUserInput,
|
|
@@ -218,7 +252,8 @@ meter / gate.
|
|
|
218
252
|
**Telemetry.** Two seams. Neither needs site configuration:
|
|
219
253
|
- `config.addRequestAttributes` — called with a flat object as the route progresses
|
|
220
254
|
(`idxGoogleStep`, `idxUserId`, `idxCreatedNewUser`, `idxRequiresUserInput`, `idxGoogleSurface`,
|
|
221
|
-
`idxGoogleMissingFieldsBehavior`, `idxAutoSignupCount`, `idxImpersonateAttempts
|
|
255
|
+
`idxGoogleMissingFieldsBehavior`, `idxAutoSignupCount`, `idxImpersonateAttempts`,
|
|
256
|
+
`idxNameBackfill`, `idxNameBackfillAttempts`). **Defaults to `utils/add-custom-attributes.js`**, which tags
|
|
222
257
|
the current New Relic transaction, so the attributes ride on the `Transaction` *and* any
|
|
223
258
|
`TransactionError` it produces — a 500 says which step failed instead of being a bare GraphQL
|
|
224
259
|
message. That default resolves the agent **only if the app already loaded it** (checks
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/access.marko",
|
|
6
6
|
marko_component = require("./access.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -53,7 +53,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
53
53
|
}, marko_component);
|
|
54
54
|
|
|
55
55
|
marko_template.meta = {
|
|
56
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
56
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/access.marko",
|
|
57
57
|
component: "./access.marko",
|
|
58
58
|
tags: [
|
|
59
59
|
"@mindful-web/marko-core/components/resolve.marko"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/comment-stream.marko",
|
|
6
6
|
marko_component = require("./comment-stream.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -91,7 +91,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
91
91
|
}, marko_component);
|
|
92
92
|
|
|
93
93
|
marko_template.meta = {
|
|
94
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
94
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/comment-stream.marko",
|
|
95
95
|
component: "./comment-stream.marko",
|
|
96
96
|
tags: [
|
|
97
97
|
"@mindful-web/marko-web/components/browser-component.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/context.marko",
|
|
6
6
|
marko_component = require("./context.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
marko_dynamicTag = require("marko/dist/runtime/helpers/dynamic-tag"),
|
|
@@ -49,7 +49,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
49
49
|
}, marko_component);
|
|
50
50
|
|
|
51
51
|
marko_template.meta = {
|
|
52
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
52
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/context.marko",
|
|
53
53
|
component: "./context.marko",
|
|
54
54
|
tags: [
|
|
55
55
|
"@mindful-web/marko-core/components/resolve.marko"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-access.marko",
|
|
6
6
|
marko_component = require("./form-access.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_defaultValue = require("@mindful-web/marko-core/utils/default-value"),
|
|
@@ -179,7 +179,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
179
179
|
}, marko_component);
|
|
180
180
|
|
|
181
181
|
marko_template.meta = {
|
|
182
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
182
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-access.marko",
|
|
183
183
|
component: "./form-access.marko",
|
|
184
184
|
tags: [
|
|
185
185
|
"@mindful-web/marko-web/components/browser-component.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-authenticate.marko",
|
|
6
6
|
marko_component = require("./form-authenticate.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -81,7 +81,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
81
81
|
}, marko_component);
|
|
82
82
|
|
|
83
83
|
marko_template.meta = {
|
|
84
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
84
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-authenticate.marko",
|
|
85
85
|
component: "./form-authenticate.marko",
|
|
86
86
|
tags: [
|
|
87
87
|
"@mindful-web/marko-web/components/browser-component.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-change-email.marko",
|
|
6
6
|
marko_component = require("./form-change-email.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -59,7 +59,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
59
59
|
}, marko_component);
|
|
60
60
|
|
|
61
61
|
marko_template.meta = {
|
|
62
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
62
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-change-email.marko",
|
|
63
63
|
component: "./form-change-email.marko",
|
|
64
64
|
tags: [
|
|
65
65
|
"@mindful-web/marko-web/components/browser-component.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-login.marko",
|
|
6
6
|
marko_component = require("./form-login.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -92,7 +92,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
92
92
|
}, marko_component);
|
|
93
93
|
|
|
94
94
|
marko_template.meta = {
|
|
95
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
95
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-login.marko",
|
|
96
96
|
component: "./form-login.marko",
|
|
97
97
|
tags: [
|
|
98
98
|
"@mindful-web/marko-web/components/browser-component.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-logout.marko",
|
|
6
6
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
7
7
|
module_defaultValue = require("@mindful-web/marko-core/utils/default-value"),
|
|
8
8
|
defaultValue = module_defaultValue.default || module_defaultValue,
|
|
@@ -29,7 +29,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
marko_template.meta = {
|
|
32
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
32
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-logout.marko",
|
|
33
33
|
tags: [
|
|
34
34
|
"@mindful-web/marko-web/components/browser-component.marko"
|
|
35
35
|
]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-profile.marko",
|
|
6
6
|
marko_component = require("./form-profile.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -84,7 +84,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
84
84
|
}, marko_component);
|
|
85
85
|
|
|
86
86
|
marko_template.meta = {
|
|
87
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
87
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-profile.marko",
|
|
88
88
|
component: "./form-profile.marko",
|
|
89
89
|
tags: [
|
|
90
90
|
"@mindful-web/marko-web/components/browser-component.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/form-register.marko",
|
|
6
6
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
7
7
|
marko_assign = require("marko/dist/runtime/helpers/assign"),
|
|
8
8
|
marko_web_identity_x_form_login_template = require("./form-login.marko"),
|
|
@@ -25,7 +25,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
marko_template.meta = {
|
|
28
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
28
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/form-register.marko",
|
|
29
29
|
tags: [
|
|
30
30
|
"./form-login.marko"
|
|
31
31
|
]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/google-init.marko",
|
|
6
6
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
7
7
|
marko_attr = require("marko/dist/runtime/html/helpers/attr"),
|
|
8
8
|
marko_str = require("marko/dist/runtime/helpers/to-string");
|
|
@@ -239,5 +239,5 @@ marko_template._ = marko_renderer(render, {
|
|
|
239
239
|
});
|
|
240
240
|
|
|
241
241
|
marko_template.meta = {
|
|
242
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
242
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/google-init.marko"
|
|
243
243
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/google-sign-in-button.marko",
|
|
6
6
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
7
7
|
helpers_escape_xml = require("marko/dist/runtime/html/helpers/escape-xml"),
|
|
8
8
|
marko_escapeXml = helpers_escape_xml.x,
|
|
@@ -40,5 +40,5 @@ marko_template._ = marko_renderer(render, {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
marko_template.meta = {
|
|
43
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
43
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/google-sign-in-button.marko"
|
|
44
44
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/identify.marko",
|
|
6
6
|
marko_component = require("./identify.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -50,7 +50,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
50
50
|
}, marko_component);
|
|
51
51
|
|
|
52
52
|
marko_template.meta = {
|
|
53
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
53
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/identify.marko",
|
|
54
54
|
component: "./identify.marko",
|
|
55
55
|
tags: [
|
|
56
56
|
"@mindful-web/marko-web-gtm/components/push.marko",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/non-auth-identify.marko",
|
|
6
6
|
marko_component = require("./non-auth-identify.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
marko_dynamicTag = require("marko/dist/runtime/helpers/dynamic-tag"),
|
|
@@ -45,7 +45,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
45
45
|
}, marko_component);
|
|
46
46
|
|
|
47
47
|
marko_template.meta = {
|
|
48
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
48
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/non-auth-identify.marko",
|
|
49
49
|
component: "./non-auth-identify.marko",
|
|
50
50
|
tags: [
|
|
51
51
|
"@mindful-web/marko-core/components/resolve.marko"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
var marko_template = module.exports = require("marko/dist/html").t(__filename),
|
|
5
|
-
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.
|
|
5
|
+
marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.2/components/subscribe.marko",
|
|
6
6
|
marko_component = require("./subscribe.marko"),
|
|
7
7
|
marko_renderer = require("marko/dist/runtime/components/renderer"),
|
|
8
8
|
module_objectPath_module = require("@mindful-web/object-path"),
|
|
@@ -73,7 +73,7 @@ marko_template._ = marko_renderer(render, {
|
|
|
73
73
|
}, marko_component);
|
|
74
74
|
|
|
75
75
|
marko_template.meta = {
|
|
76
|
-
id: "/@mindful-web/marko-web-identity-x$1.80.
|
|
76
|
+
id: "/@mindful-web/marko-web-identity-x$1.80.2/components/subscribe.marko",
|
|
77
77
|
component: "./subscribe.marko",
|
|
78
78
|
tags: [
|
|
79
79
|
"@mindful-web/marko-web/components/browser-component.marko",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mindful-web/marko-web-identity-x",
|
|
3
|
-
"version": "1.80.
|
|
3
|
+
"version": "1.80.2",
|
|
4
4
|
"description": "Marko Wrapper for IdentityX",
|
|
5
5
|
"repository": "https://github.com/parameter1/mindful-web/tree/main/packages/marko-web-identity-x",
|
|
6
6
|
"author": "Josh Worden <josh@parameter1.com>",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"test": "yarn compile --no-clean && yarn lint"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@mindful-web/marko-web-gtm": "^1.80.
|
|
17
|
-
"@mindful-web/object-path": "^1.80.
|
|
18
|
-
"@mindful-web/utils": "^1.80.
|
|
16
|
+
"@mindful-web/marko-web-gtm": "^1.80.2",
|
|
17
|
+
"@mindful-web/object-path": "^1.80.2",
|
|
18
|
+
"@mindful-web/utils": "^1.80.2",
|
|
19
19
|
"apollo-cache-inmemory": "^1.6.6",
|
|
20
20
|
"apollo-client": "^2.6.10",
|
|
21
21
|
"apollo-link-context": "^1.0.20",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "59e2be57d4905ab42c5acfa590c270a8c12bfce7"
|
|
42
42
|
}
|
package/routes/google.js
CHANGED
|
@@ -33,6 +33,24 @@ const LOGIN_SOURCE = 'google-one-tap';
|
|
|
33
33
|
const IMPERSONATE_MAX_ATTEMPTS = 2;
|
|
34
34
|
const IMPERSONATE_RETRY_DELAY_MS = 250;
|
|
35
35
|
|
|
36
|
+
// Same shape as the impersonation retry, and for the same suspected cause: a
|
|
37
|
+
// read-after-write race, this time on the token the previous step just minted.
|
|
38
|
+
const NAME_BACKFILL_MAX_ATTEMPTS = 2;
|
|
39
|
+
const NAME_BACKFILL_RETRY_DELAY_MS = 250;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A session token that the idx API does not (yet) recognise.
|
|
43
|
+
*
|
|
44
|
+
* Apollo exposes GraphQL errors both individually on `graphQLErrors` and folded
|
|
45
|
+
* into `error.message` as "GraphQL error: <message>"; check both so this does not
|
|
46
|
+
* depend on which shape the caller happens to see.
|
|
47
|
+
*/
|
|
48
|
+
const isFreshTokenError = (e) => {
|
|
49
|
+
if (!e) return false;
|
|
50
|
+
const messages = [e.message, ...asArray(e.graphQLErrors).map((g) => g && g.message)];
|
|
51
|
+
return messages.some((m) => /not a valid token|invalid token|token was not found/i.test(String(m)));
|
|
52
|
+
};
|
|
53
|
+
|
|
36
54
|
/**
|
|
37
55
|
* Transport-level failures only — a timeout, reset or DNS blip is worth
|
|
38
56
|
* repeating; a GraphQL validation or authorization error is not, and repeating
|
|
@@ -266,10 +284,55 @@ module.exports = asyncRoute(async (req, res) => {
|
|
|
266
284
|
if (familyName && !appUser.familyName) nameInput.familyName = familyName;
|
|
267
285
|
if (Object.keys(nameInput).length) {
|
|
268
286
|
setStep('update-own-app-user');
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
287
|
+
// This is the ONLY call in the route authenticated as the *user* rather than
|
|
288
|
+
// the org — every other one passes `context: { apiToken: getOrgUserApiToken() }`
|
|
289
|
+
// — so it is the only one that depends on the session token minted moments
|
|
290
|
+
// earlier already being readable. That is exactly why it is the only
|
|
291
|
+
// operation reported failing: production shows `GoogleSignInUpdateUser`
|
|
292
|
+
// returning "The provided value is not a valid token".
|
|
293
|
+
//
|
|
294
|
+
// The same token value works on the *next* request, arriving from the cookie
|
|
295
|
+
// set above — which is what makes a read-after-write race on the idx token
|
|
296
|
+
// store the leading explanation, so retry once.
|
|
297
|
+
//
|
|
298
|
+
// Non-fatal regardless of the cause, which matters more than the retry. This
|
|
299
|
+
// backfills a first and last name; it is cosmetic. But `tokenCookie.setTo`
|
|
300
|
+
// has already run, so the user IS authenticated by the time we get here —
|
|
301
|
+
// throwing turned a fully successful sign-in into a 500, and the client, on
|
|
302
|
+
// seeing `!data.ok`, ran `fail()` and redirected a logged-in user to
|
|
303
|
+
// /user/login. A missing display name must never cost someone their session.
|
|
304
|
+
let backfill = 'ok';
|
|
305
|
+
let attempts = 0;
|
|
306
|
+
for (;;) {
|
|
307
|
+
attempts += 1;
|
|
308
|
+
try {
|
|
309
|
+
// eslint-disable-next-line no-await-in-loop
|
|
310
|
+
await identityX.client.mutate({
|
|
311
|
+
mutation: UPDATE_OWN_APP_USER,
|
|
312
|
+
variables: { input: nameInput },
|
|
313
|
+
});
|
|
314
|
+
break;
|
|
315
|
+
} catch (e) {
|
|
316
|
+
const retryable = attempts < NAME_BACKFILL_MAX_ATTEMPTS
|
|
317
|
+
&& (isFreshTokenError(e) || isRetryableIdxError(e));
|
|
318
|
+
if (!retryable) {
|
|
319
|
+
backfill = 'failed';
|
|
320
|
+
onError(e, {
|
|
321
|
+
idxGoogleStep: 'update-own-app-user',
|
|
322
|
+
idxUserId: appUser.id,
|
|
323
|
+
idxNameBackfillAttempts: attempts,
|
|
324
|
+
});
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
backfill = 'retried';
|
|
328
|
+
// eslint-disable-next-line no-await-in-loop
|
|
329
|
+
await sleep(NAME_BACKFILL_RETRY_DELAY_MS);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// Measurable: `FACET idxNameBackfill` separates "the retry rescues it" (a
|
|
333
|
+
// race) from "it always fails" (an impersonation token that simply cannot
|
|
334
|
+
// authorize this mutation) — two different bugs with one error message.
|
|
335
|
+
addAttrs({ idxNameBackfill: backfill, idxNameBackfillAttempts: attempts });
|
|
273
336
|
}
|
|
274
337
|
|
|
275
338
|
// Load the refreshed user so hooks and field checks have up-to-date data.
|