@remit/backend 0.0.130 → 0.0.131
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/package.json
CHANGED
|
@@ -251,7 +251,7 @@ describe("the Microsoft consent for the services an account syncs", () => {
|
|
|
251
251
|
|
|
252
252
|
assert.equal(
|
|
253
253
|
location,
|
|
254
|
-
`${WEB_ORIGIN}/settings/accounts?oauthError=scope_not_granted`,
|
|
254
|
+
`${WEB_ORIGIN}/settings/accounts?oauthError=scope_not_granted&oauthEmail=person%40example.com&missingServices=Calendar`,
|
|
255
255
|
);
|
|
256
256
|
assert.deepEqual(
|
|
257
257
|
await client.account.listAllByAccountConfig(deriveAccountConfigId(sub)),
|
|
@@ -236,7 +236,24 @@ export function getWebOrigin(): string {
|
|
|
236
236
|
|
|
237
237
|
type ScopeRedemption =
|
|
238
238
|
| { kind: "granted"; refreshToken: string; grantedScopes: string[] }
|
|
239
|
-
| { kind: "refused"; reason: "exchange_failed"
|
|
239
|
+
| { kind: "refused"; reason: "exchange_failed" }
|
|
240
|
+
| {
|
|
241
|
+
kind: "refused";
|
|
242
|
+
reason: "scope_not_granted";
|
|
243
|
+
service: AccountServiceName;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const scopeRefusalUrl = (
|
|
247
|
+
webOrigin: string,
|
|
248
|
+
email: string,
|
|
249
|
+
missingServices: readonly AccountServiceName[],
|
|
250
|
+
): string => {
|
|
251
|
+
const url = new URL(`${webOrigin}/settings/accounts`);
|
|
252
|
+
url.searchParams.set("oauthError", "scope_not_granted");
|
|
253
|
+
url.searchParams.set("oauthEmail", email);
|
|
254
|
+
url.searchParams.set("missingServices", missingServices.join(","));
|
|
255
|
+
return url.toString();
|
|
256
|
+
};
|
|
240
257
|
|
|
241
258
|
const redeemEachService = async (
|
|
242
259
|
serviceFor: (service: AccountServiceName) => MailOAuthService,
|
|
@@ -265,8 +282,10 @@ const redeemEachService = async (
|
|
|
265
282
|
? ("exchange_failed" as const)
|
|
266
283
|
: ("scope_not_granted" as const);
|
|
267
284
|
});
|
|
268
|
-
if (
|
|
285
|
+
if (redeemed === "exchange_failed")
|
|
269
286
|
return { kind: "refused", reason: redeemed };
|
|
287
|
+
if (redeemed === "scope_not_granted")
|
|
288
|
+
return { kind: "refused", reason: redeemed, service };
|
|
270
289
|
grantedScopes.push(...redeemed.grantedScopes);
|
|
271
290
|
token = redeemed.refreshToken ?? token;
|
|
272
291
|
}
|
|
@@ -512,6 +531,11 @@ export const MicrosoftOAuthOperations: Record<
|
|
|
512
531
|
services.filter((service) => service !== firstService),
|
|
513
532
|
accountConfigId,
|
|
514
533
|
);
|
|
534
|
+
if (
|
|
535
|
+
redemption.kind === "refused" &&
|
|
536
|
+
redemption.reason === "scope_not_granted"
|
|
537
|
+
)
|
|
538
|
+
return redirect(scopeRefusalUrl(webOrigin, email, [redemption.service]));
|
|
515
539
|
if (redemption.kind === "refused")
|
|
516
540
|
return redirect(
|
|
517
541
|
`${webOrigin}/settings/accounts?oauthError=${redemption.reason}`,
|
|
@@ -535,9 +559,7 @@ export const MicrosoftOAuthOperations: Record<
|
|
|
535
559
|
},
|
|
536
560
|
"MS OAuth callback: granted scopes lack a requested service",
|
|
537
561
|
);
|
|
538
|
-
return redirect(
|
|
539
|
-
`${webOrigin}/settings/accounts?oauthError=scope_not_granted`,
|
|
540
|
-
);
|
|
562
|
+
return redirect(scopeRefusalUrl(webOrigin, email, missingServices));
|
|
541
563
|
}
|
|
542
564
|
|
|
543
565
|
// Ensure the account config row exists for this user
|