hazo_auth 10.4.8 → 10.4.9
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.
|
@@ -175,9 +175,22 @@ export function get_nextauth_config(): AuthOptions {
|
|
|
175
175
|
// Store user_id in account for the JWT callback to pick up
|
|
176
176
|
(account as Record<string, unknown>).hazo_user_id = result.user_id;
|
|
177
177
|
|
|
178
|
-
// Capture refresh token when extra scopes were granted
|
|
178
|
+
// Capture refresh token when extra scopes were granted.
|
|
179
|
+
// Google echoes the base scopes back in full-URL form
|
|
180
|
+
// (https://www.googleapis.com/auth/userinfo.email|profile), so we
|
|
181
|
+
// normalise to short names before comparing — otherwise every plain
|
|
182
|
+
// login looks like it requested extra scopes and triggers offline
|
|
183
|
+
// token storage that should never run.
|
|
179
184
|
const BASE_SCOPES = ["openid", "email", "profile"];
|
|
180
|
-
const
|
|
185
|
+
const normalise_scope = (s: string): string => {
|
|
186
|
+
if (s === "https://www.googleapis.com/auth/userinfo.email") return "email";
|
|
187
|
+
if (s === "https://www.googleapis.com/auth/userinfo.profile") return "profile";
|
|
188
|
+
return s;
|
|
189
|
+
};
|
|
190
|
+
const granted_scopes = (account.scope ?? "")
|
|
191
|
+
.split(" ")
|
|
192
|
+
.filter(Boolean)
|
|
193
|
+
.map(normalise_scope);
|
|
181
194
|
const has_extra_scopes = granted_scopes.some(s => !BASE_SCOPES.includes(s));
|
|
182
195
|
|
|
183
196
|
if (account.refresh_token && has_extra_scopes) {
|
|
@@ -197,17 +210,23 @@ export function get_nextauth_config(): AuthOptions {
|
|
|
197
210
|
});
|
|
198
211
|
} catch (tokenError) {
|
|
199
212
|
if (tokenError instanceof GoogleTokenStorageUnconfigured) {
|
|
200
|
-
|
|
213
|
+
// Non-fatal: offline Google API access (refresh-token storage)
|
|
214
|
+
// requires HAZO_AUTH_OAUTH_KEY_* encryption keys. Login itself
|
|
215
|
+
// does not — the user already authenticated. Warn so the admin
|
|
216
|
+
// can configure keys if they want offline access, but let the
|
|
217
|
+
// sign-in complete instead of dead-ending on an error page.
|
|
218
|
+
logger.warn("nextauth_google_token_storage_unconfigured", {
|
|
201
219
|
user_id: result.user_id,
|
|
202
220
|
error: tokenError.message,
|
|
221
|
+
impact: "Login succeeded; offline Google API access disabled until HAZO_AUTH_OAUTH_KEY_CURRENT and HAZO_AUTH_OAUTH_KEY_<ID> are set.",
|
|
222
|
+
});
|
|
223
|
+
} else {
|
|
224
|
+
const errorMsg = tokenError instanceof Error ? tokenError.message : String(tokenError);
|
|
225
|
+
logger.error("nextauth_google_token_store_failed", {
|
|
226
|
+
user_id: result.user_id,
|
|
227
|
+
error: errorMsg,
|
|
203
228
|
});
|
|
204
|
-
return "/api/auth/error?error=GoogleTokenStorageUnconfigured";
|
|
205
229
|
}
|
|
206
|
-
const errorMsg = tokenError instanceof Error ? tokenError.message : String(tokenError);
|
|
207
|
-
logger.error("nextauth_google_token_store_failed", {
|
|
208
|
-
user_id: result.user_id,
|
|
209
|
-
error: errorMsg,
|
|
210
|
-
});
|
|
211
230
|
// Non-fatal: continue sign-in even if token storage fails
|
|
212
231
|
}
|
|
213
232
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextauth_config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/nextauth_config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,WAAW,CAAC;AAetD,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,
|
|
1
|
+
{"version":3,"file":"nextauth_config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/nextauth_config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,WAAW,CAAC;AAetD,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CA2RjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAW7C"}
|
|
@@ -116,9 +116,24 @@ export function get_nextauth_config() {
|
|
|
116
116
|
});
|
|
117
117
|
// Store user_id in account for the JWT callback to pick up
|
|
118
118
|
account.hazo_user_id = result.user_id;
|
|
119
|
-
// Capture refresh token when extra scopes were granted
|
|
119
|
+
// Capture refresh token when extra scopes were granted.
|
|
120
|
+
// Google echoes the base scopes back in full-URL form
|
|
121
|
+
// (https://www.googleapis.com/auth/userinfo.email|profile), so we
|
|
122
|
+
// normalise to short names before comparing — otherwise every plain
|
|
123
|
+
// login looks like it requested extra scopes and triggers offline
|
|
124
|
+
// token storage that should never run.
|
|
120
125
|
const BASE_SCOPES = ["openid", "email", "profile"];
|
|
121
|
-
const
|
|
126
|
+
const normalise_scope = (s) => {
|
|
127
|
+
if (s === "https://www.googleapis.com/auth/userinfo.email")
|
|
128
|
+
return "email";
|
|
129
|
+
if (s === "https://www.googleapis.com/auth/userinfo.profile")
|
|
130
|
+
return "profile";
|
|
131
|
+
return s;
|
|
132
|
+
};
|
|
133
|
+
const granted_scopes = ((_b = account.scope) !== null && _b !== void 0 ? _b : "")
|
|
134
|
+
.split(" ")
|
|
135
|
+
.filter(Boolean)
|
|
136
|
+
.map(normalise_scope);
|
|
122
137
|
const has_extra_scopes = granted_scopes.some(s => !BASE_SCOPES.includes(s));
|
|
123
138
|
if (account.refresh_token && has_extra_scopes) {
|
|
124
139
|
try {
|
|
@@ -138,17 +153,24 @@ export function get_nextauth_config() {
|
|
|
138
153
|
}
|
|
139
154
|
catch (tokenError) {
|
|
140
155
|
if (tokenError instanceof GoogleTokenStorageUnconfigured) {
|
|
141
|
-
|
|
156
|
+
// Non-fatal: offline Google API access (refresh-token storage)
|
|
157
|
+
// requires HAZO_AUTH_OAUTH_KEY_* encryption keys. Login itself
|
|
158
|
+
// does not — the user already authenticated. Warn so the admin
|
|
159
|
+
// can configure keys if they want offline access, but let the
|
|
160
|
+
// sign-in complete instead of dead-ending on an error page.
|
|
161
|
+
logger.warn("nextauth_google_token_storage_unconfigured", {
|
|
142
162
|
user_id: result.user_id,
|
|
143
163
|
error: tokenError.message,
|
|
164
|
+
impact: "Login succeeded; offline Google API access disabled until HAZO_AUTH_OAUTH_KEY_CURRENT and HAZO_AUTH_OAUTH_KEY_<ID> are set.",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const errorMsg = tokenError instanceof Error ? tokenError.message : String(tokenError);
|
|
169
|
+
logger.error("nextauth_google_token_store_failed", {
|
|
170
|
+
user_id: result.user_id,
|
|
171
|
+
error: errorMsg,
|
|
144
172
|
});
|
|
145
|
-
return "/api/auth/error?error=GoogleTokenStorageUnconfigured";
|
|
146
173
|
}
|
|
147
|
-
const errorMsg = tokenError instanceof Error ? tokenError.message : String(tokenError);
|
|
148
|
-
logger.error("nextauth_google_token_store_failed", {
|
|
149
|
-
user_id: result.user_id,
|
|
150
|
-
error: errorMsg,
|
|
151
|
-
});
|
|
152
174
|
// Non-fatal: continue sign-in even if token storage fails
|
|
153
175
|
}
|
|
154
176
|
}
|
package/package.json
CHANGED