@exegia/corpora-ui 0.9.0 → 0.10.0
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/dist-lib/components/blocks/auth/linked-accounts-block.d.ts +7 -1
- package/dist-lib/index.js +26 -26
- package/dist-lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/blocks/auth/__tests__/linked-accounts-block.test.tsx +18 -0
- package/src/components/blocks/auth/linked-accounts-block.tsx +10 -2
package/package.json
CHANGED
|
@@ -89,6 +89,24 @@ describe("LinkedAccountsBlock", () => {
|
|
|
89
89
|
expect(onUnlink).not.toHaveBeenCalled();
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
+
test("lifts the guard when another sign-in method exists off-list", async () => {
|
|
93
|
+
const user = userEvent.setup();
|
|
94
|
+
const onUnlink = mock(async () => {});
|
|
95
|
+
render(
|
|
96
|
+
<LinkedAccountsBlock
|
|
97
|
+
identities={[IDENTITIES[0]!]}
|
|
98
|
+
hasOtherSignInMethods
|
|
99
|
+
onUnlink={onUnlink}
|
|
100
|
+
/>,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const button = screen.getByRole("button", { name: "Disconnect Google" });
|
|
104
|
+
expect(button.hasAttribute("disabled")).toBe(false);
|
|
105
|
+
|
|
106
|
+
await user.click(button);
|
|
107
|
+
expect(onUnlink).toHaveBeenCalledWith("id-1");
|
|
108
|
+
});
|
|
109
|
+
|
|
92
110
|
test("surfaces a failing link as an error", async () => {
|
|
93
111
|
const user = userEvent.setup();
|
|
94
112
|
render(
|
|
@@ -36,6 +36,12 @@ export interface LinkedAccountsBlockProps {
|
|
|
36
36
|
providers?: SocialProvider[];
|
|
37
37
|
/** Shows the loading row instead of the list. */
|
|
38
38
|
loading?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* The account can also sign in through a method that has no row in this
|
|
41
|
+
* list — an email/password credential, say. Lifts the last-method guard,
|
|
42
|
+
* which otherwise refuses to disconnect the final listed identity.
|
|
43
|
+
*/
|
|
44
|
+
hasOtherSignInMethods?: boolean;
|
|
39
45
|
/** Reject (or throw) to show the inline error. */
|
|
40
46
|
onLink?: (provider: SocialProvider) => Promise<void> | void;
|
|
41
47
|
onUnlink?: (id: string) => Promise<void> | void;
|
|
@@ -57,6 +63,7 @@ export function LinkedAccountsBlock({
|
|
|
57
63
|
identities = [],
|
|
58
64
|
providers = ["google", "apple", "github"],
|
|
59
65
|
loading = false,
|
|
66
|
+
hasOtherSignInMethods = false,
|
|
60
67
|
onLink,
|
|
61
68
|
onUnlink,
|
|
62
69
|
className,
|
|
@@ -70,8 +77,9 @@ export function LinkedAccountsBlock({
|
|
|
70
77
|
const connectable = providers.filter((provider) => !connected.has(provider));
|
|
71
78
|
const busy = linking !== null || unlinking !== null;
|
|
72
79
|
// The backend rule, enforced here so we never fire a request that would
|
|
73
|
-
// remove the account's only way in.
|
|
74
|
-
|
|
80
|
+
// remove the account's only way in. An off-list method (a password) keeps
|
|
81
|
+
// the account reachable, so it lifts the guard.
|
|
82
|
+
const lastMethod = !hasOtherSignInMethods && identities.length <= 1;
|
|
75
83
|
|
|
76
84
|
async function connect(provider: SocialProvider) {
|
|
77
85
|
if (busy) return;
|