@slashid/jump-page 0.0.7-beta.0 → 0.0.7-beta.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/cli.js +16 -19
- package/dist/_astro/app.f7d04798.js +39 -0
- package/dist/_astro/client.a5ffbec0.js +24 -0
- package/dist/_astro/index.03be2d59.js +9 -0
- package/dist/_astro/index.2dd0ad08.css +1 -0
- package/dist/_astro/index.cc62d81f.css +1 -0
- package/dist/index.html +7 -0
- package/package.json +9 -1
- package/.turbo/turbo-build.log +0 -32
- package/.vscode/extensions.json +0 -4
- package/.vscode/launch.json +0 -11
- package/CHANGELOG.md +0 -37
- package/src/components/README.md +0 -3
- package/src/components/app/app.component.tsx +0 -83
- package/src/components/app/app.context.tsx +0 -41
- package/src/components/app/app.css.ts +0 -15
- package/src/components/app/index.ts +0 -1
- package/src/components/card/card.component.tsx +0 -42
- package/src/components/card/card.css.ts +0 -40
- package/src/components/card/index.ts +0 -1
- package/src/components/flow/flow.component.tsx +0 -99
- package/src/components/flow/flow.css.ts +0 -20
- package/src/components/flow/flow.domain.ts +0 -18
- package/src/components/flow/flow.error.tsx +0 -32
- package/src/components/flow/flow.initial.tsx +0 -14
- package/src/components/flow/flow.loader.tsx +0 -9
- package/src/components/flow/flow.progress.tsx +0 -119
- package/src/components/flow/flow.recover.tsx +0 -121
- package/src/components/flow/flow.success.tsx +0 -40
- package/src/components/flow/flow.types.ts +0 -48
- package/src/components/flow/index.ts +0 -3
- package/src/components/text/index.ts +0 -1
- package/src/components/text/text.component.tsx +0 -8
- package/src/components/text/use-i18n.ts +0 -13
- package/src/config.ts +0 -13
- package/src/domain/i18n.ts +0 -115
- package/src/env.d.ts +0 -1
- package/src/layouts/README.md +0 -3
- package/src/layouts/page.astro +0 -33
- package/src/pages/index.astro +0 -8
- /package/{public → dist}/favicon.png +0 -0
package/.turbo/turbo-build.log
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @slashid/jump-page@0.0.6 build /Users/ivankovic/projects/slashid/javascript/apps/jump-page
|
|
3
|
-
> astro build
|
|
4
|
-
|
|
5
|
-
05:00:06 PM [content] No content directory found. Skipping type generation.
|
|
6
|
-
05:00:06 PM [build] output target: static
|
|
7
|
-
05:00:06 PM [build] Collecting build info...
|
|
8
|
-
05:00:06 PM [build] Completed in 111ms.
|
|
9
|
-
05:00:06 PM [build] Building static entrypoints...
|
|
10
|
-
05:00:07 PM [build] Completed in 1.68s.
|
|
11
|
-
|
|
12
|
-
building client
|
|
13
|
-
vite v4.5.0 building for production...
|
|
14
|
-
transforming...
|
|
15
|
-
✓ 384 modules transformed.
|
|
16
|
-
rendering chunks...
|
|
17
|
-
computing gzip size...
|
|
18
|
-
dist/_astro/index.cc62d81f.css 31.75 kB │ gzip: 5.49 kB
|
|
19
|
-
dist/_astro/index.03be2d59.js 6.83 kB │ gzip: 2.72 kB
|
|
20
|
-
dist/_astro/client.a5ffbec0.js 135.34 kB │ gzip: 43.73 kB
|
|
21
|
-
dist/_astro/app.51fc6a0f.js 203.42 kB │ gzip: 56.61 kB
|
|
22
|
-
✓ built in 1.94s
|
|
23
|
-
Completed in 1.95s.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
generating static routes
|
|
27
|
-
▶ src/pages/index.astro
|
|
28
|
-
└─ /index.html (+122ms)
|
|
29
|
-
Completed in 132ms.
|
|
30
|
-
|
|
31
|
-
05:00:09 PM [build] 1 page(s) built in 3.88s
|
|
32
|
-
05:00:09 PM [build] Complete!
|
package/.vscode/extensions.json
DELETED
package/.vscode/launch.json
DELETED
package/CHANGELOG.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# @slashid/jump-page
|
|
2
|
-
|
|
3
|
-
## 0.0.6
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- Updated dependencies [64212fd]
|
|
8
|
-
- @slashid/react-primitives@0.1.4
|
|
9
|
-
|
|
10
|
-
## 0.0.5
|
|
11
|
-
|
|
12
|
-
### Patch Changes
|
|
13
|
-
|
|
14
|
-
- Updated dependencies [21c2948]
|
|
15
|
-
- @slashid/react-primitives@0.1.3
|
|
16
|
-
|
|
17
|
-
## 0.0.4
|
|
18
|
-
|
|
19
|
-
### Patch Changes
|
|
20
|
-
|
|
21
|
-
- Updated dependencies [0e2fb6b]
|
|
22
|
-
- @slashid/react-primitives@0.1.2
|
|
23
|
-
|
|
24
|
-
## 0.0.3
|
|
25
|
-
|
|
26
|
-
### Patch Changes
|
|
27
|
-
|
|
28
|
-
- Updated dependencies [0e4746c]
|
|
29
|
-
- @slashid/react-primitives@0.1.1
|
|
30
|
-
|
|
31
|
-
## 0.0.2
|
|
32
|
-
|
|
33
|
-
### Patch Changes
|
|
34
|
-
|
|
35
|
-
- c1cf068: Update dependencies
|
|
36
|
-
- Updated dependencies [c1cf068]
|
|
37
|
-
- @slashid/react-primitives@0.1.0
|
package/src/components/README.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { SlashID } from "@slashid/slashid";
|
|
2
|
-
import * as Sentry from "@sentry/react";
|
|
3
|
-
import {
|
|
4
|
-
Logo,
|
|
5
|
-
TextProvider,
|
|
6
|
-
ThemeRoot,
|
|
7
|
-
isBrowser,
|
|
8
|
-
} from "@slashid/react-primitives";
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
AppContext,
|
|
12
|
-
initialAppContextState,
|
|
13
|
-
type AppState,
|
|
14
|
-
type AppContextState,
|
|
15
|
-
type AppReadyState,
|
|
16
|
-
} from "./app.context";
|
|
17
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
18
|
-
import { I18N, detectLanguage } from "../../domain/i18n";
|
|
19
|
-
import { Flow, Error } from "../flow";
|
|
20
|
-
import { Card } from "../card";
|
|
21
|
-
|
|
22
|
-
import * as styles from "./app.css";
|
|
23
|
-
import { config } from "../../config";
|
|
24
|
-
|
|
25
|
-
export function App() {
|
|
26
|
-
const isClientSide = isBrowser();
|
|
27
|
-
const [appState, setAppState] = useState<AppState>("initial");
|
|
28
|
-
const sidRef = useRef<SlashID | undefined>(undefined);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (appState === "initial") {
|
|
32
|
-
Sentry.init({
|
|
33
|
-
dsn: "https://6435e8a20ba8b61404fb4621d2aedd4a@o4505317722619904.ingest.sentry.io/4506275681075200",
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
sidRef.current = new SlashID({
|
|
37
|
-
analyticsEnabled: false,
|
|
38
|
-
sdkURL: config.sdkURL,
|
|
39
|
-
baseURL: config.baseURL,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
setAppState("ready");
|
|
43
|
-
}
|
|
44
|
-
}, [appState]);
|
|
45
|
-
|
|
46
|
-
const state: AppContextState = useMemo(() => {
|
|
47
|
-
// checking for hydration makes the first client side render the same as the one on the server side
|
|
48
|
-
// language check and URL params can only be done on the client side so we need to wait for the first render
|
|
49
|
-
if (!isClientSide || appState == "initial") {
|
|
50
|
-
return initialAppContextState;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const appReadyState: AppReadyState = {
|
|
54
|
-
// TODO read customisation props from the URL
|
|
55
|
-
logo: <Logo />,
|
|
56
|
-
language: detectLanguage(),
|
|
57
|
-
state: appState,
|
|
58
|
-
sdk: sidRef.current as SlashID,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
return appReadyState;
|
|
62
|
-
}, [appState, isClientSide]);
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<ThemeRoot theme="light">
|
|
66
|
-
<Sentry.ErrorBoundary
|
|
67
|
-
fallback={
|
|
68
|
-
<Card>
|
|
69
|
-
<Error type="error" />
|
|
70
|
-
</Card>
|
|
71
|
-
}
|
|
72
|
-
>
|
|
73
|
-
<AppContext.Provider value={state}>
|
|
74
|
-
<TextProvider text={I18N[state.language]}>
|
|
75
|
-
<main className={styles.app}>
|
|
76
|
-
<Flow />
|
|
77
|
-
</main>
|
|
78
|
-
</TextProvider>
|
|
79
|
-
</AppContext.Provider>
|
|
80
|
-
</Sentry.ErrorBoundary>
|
|
81
|
-
</ThemeRoot>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from "react";
|
|
2
|
-
import { Logo } from "@slashid/react-primitives";
|
|
3
|
-
import type { SlashID } from "@slashid/slashid";
|
|
4
|
-
|
|
5
|
-
import { type Language } from "../../domain/i18n";
|
|
6
|
-
|
|
7
|
-
export type AppState = "initial" | "ready";
|
|
8
|
-
|
|
9
|
-
type AppConfig = {
|
|
10
|
-
logo: string | React.ReactNode;
|
|
11
|
-
language: Language;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type AppInitialState = AppConfig & {
|
|
15
|
-
state: "initial";
|
|
16
|
-
sdk: undefined;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type AppReadyState = AppConfig & {
|
|
20
|
-
state: "ready";
|
|
21
|
-
sdk: SlashID;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type AppContextState = AppInitialState | AppReadyState;
|
|
25
|
-
|
|
26
|
-
export const initialAppContextState: AppContextState = {
|
|
27
|
-
logo: <Logo />,
|
|
28
|
-
language: "en",
|
|
29
|
-
state: "initial",
|
|
30
|
-
sdk: undefined,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export const AppContext = createContext<AppContextState>(
|
|
34
|
-
initialAppContextState
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
export const useAppContext = () => {
|
|
38
|
-
const appContext = useContext(AppContext);
|
|
39
|
-
|
|
40
|
-
return appContext;
|
|
41
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { publicVariables } from "@slashid/react-primitives";
|
|
2
|
-
import { style } from "@vanilla-extract/css";
|
|
3
|
-
|
|
4
|
-
export const app = style({
|
|
5
|
-
fontFamily: publicVariables.font.fontFamily,
|
|
6
|
-
backgroundColor: publicVariables.color.background,
|
|
7
|
-
boxSizing: "border-box",
|
|
8
|
-
display: "flex",
|
|
9
|
-
justifyContent: "center",
|
|
10
|
-
alignItems: "center",
|
|
11
|
-
width: "100%",
|
|
12
|
-
height: "100vh",
|
|
13
|
-
padding: 0,
|
|
14
|
-
margin: 0,
|
|
15
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./app.component";
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { useAppContext } from "../app/app.context";
|
|
2
|
-
import { Text } from "../text";
|
|
3
|
-
import * as styles from "./card.css";
|
|
4
|
-
|
|
5
|
-
export type Props = {
|
|
6
|
-
children: React.ReactNode;
|
|
7
|
-
footer?: React.ReactNode;
|
|
8
|
-
header?: React.ReactNode;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
function DefaultHeader() {
|
|
12
|
-
const { logo } = useAppContext();
|
|
13
|
-
|
|
14
|
-
return <div className={styles.logo}>{logo}</div>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function DefaultFooter() {
|
|
18
|
-
return (
|
|
19
|
-
<Text
|
|
20
|
-
t="footer.text"
|
|
21
|
-
variant={{
|
|
22
|
-
size: "xs",
|
|
23
|
-
weight: "semibold",
|
|
24
|
-
color: "placeholder",
|
|
25
|
-
}}
|
|
26
|
-
/>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function Card({
|
|
31
|
-
children,
|
|
32
|
-
header = <DefaultHeader />,
|
|
33
|
-
footer = <DefaultFooter />,
|
|
34
|
-
}: Props) {
|
|
35
|
-
return (
|
|
36
|
-
<article className={styles.card}>
|
|
37
|
-
{header && <header className={styles.header}>{header}</header>}
|
|
38
|
-
<div>{children}</div>
|
|
39
|
-
{footer && <footer className={styles.footer}>{footer}</footer>}
|
|
40
|
-
</article>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { publicVariables, theme } from "@slashid/react-primitives";
|
|
2
|
-
import { globalStyle, style } from "@vanilla-extract/css";
|
|
3
|
-
|
|
4
|
-
export const card = style({
|
|
5
|
-
display: "grid",
|
|
6
|
-
gridTemplateRows: "auto 1fr auto",
|
|
7
|
-
backgroundColor: publicVariables.color.panel,
|
|
8
|
-
width: "100%",
|
|
9
|
-
minHeight: "100vh",
|
|
10
|
-
padding: "32px 32px 16px 32px",
|
|
11
|
-
boxSizing: "border-box",
|
|
12
|
-
|
|
13
|
-
"@media": {
|
|
14
|
-
"screen and (min-width: 768px)": {
|
|
15
|
-
borderRadius: `calc(2 * ${publicVariables.border.radius})`,
|
|
16
|
-
width: "465px",
|
|
17
|
-
minHeight: "330px",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
export const header = style({
|
|
23
|
-
marginBottom: theme.space[1],
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
export const footer = style({
|
|
27
|
-
width: "100%",
|
|
28
|
-
textAlign: "center",
|
|
29
|
-
marginTop: theme.space[8],
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
export const logo = style({
|
|
33
|
-
width: 32,
|
|
34
|
-
height: 32,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
globalStyle(`${logo} > svg`, {
|
|
38
|
-
height: 32,
|
|
39
|
-
width: 32,
|
|
40
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./card.component";
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import * as Sentry from "@sentry/react";
|
|
3
|
-
import { Card } from "../card";
|
|
4
|
-
import { Initial } from "./flow.initial";
|
|
5
|
-
import { Error } from "./flow.error";
|
|
6
|
-
import type { Challenges, State, FlowType } from "./flow.types";
|
|
7
|
-
import { useAppContext } from "../app/app.context";
|
|
8
|
-
import { Progress } from "./flow.progress";
|
|
9
|
-
import type { ChallengeListInner } from "@slashid/slashid";
|
|
10
|
-
import { Success } from "./flow.success";
|
|
11
|
-
import { ensureError } from "./flow.domain";
|
|
12
|
-
|
|
13
|
-
function isPasswordRecoveryFlow(challenges: Challenges): boolean {
|
|
14
|
-
return challenges.some((challenge) => challenge.type === "password_reset");
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function getFlowTypeFromChallenges(challenges: Challenges): FlowType {
|
|
18
|
-
if (isPasswordRecoveryFlow(challenges)) {
|
|
19
|
-
return "password-recovery";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return "catch-all";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function Flow() {
|
|
26
|
-
const [flowState, setFlowState] = useState<State>({ state: "initial" });
|
|
27
|
-
const { sdk, state: appState } = useAppContext();
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
if (flowState.state !== "initial") return;
|
|
31
|
-
|
|
32
|
-
async function processChallenges() {
|
|
33
|
-
if (!sdk) return;
|
|
34
|
-
setFlowState({ state: "parsing-url" });
|
|
35
|
-
|
|
36
|
-
let challenges: ChallengeListInner[] | null = [];
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
challenges = await sdk.getChallengesFromURL();
|
|
40
|
-
} catch (e: unknown) {
|
|
41
|
-
Sentry.captureException(ensureError(e));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!challenges) {
|
|
45
|
-
setFlowState({ state: "no-challenges", challenges: null });
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const flowType = getFlowTypeFromChallenges(challenges);
|
|
50
|
-
|
|
51
|
-
setFlowState({ state: "progress", challenges, flowType });
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
processChallenges();
|
|
55
|
-
}, [appState, flowState.state, sdk]);
|
|
56
|
-
|
|
57
|
-
const handleSuccess = () => {
|
|
58
|
-
if (flowState.state !== "progress") return;
|
|
59
|
-
|
|
60
|
-
setFlowState({
|
|
61
|
-
state: "success",
|
|
62
|
-
challenges: flowState.challenges,
|
|
63
|
-
flowType: flowState.flowType,
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const handleError = ({ error }: { error: Error }) => {
|
|
68
|
-
if (flowState.state !== "progress") return;
|
|
69
|
-
|
|
70
|
-
setFlowState({
|
|
71
|
-
state: "error",
|
|
72
|
-
challenges: flowState.challenges,
|
|
73
|
-
flowType: flowState.flowType,
|
|
74
|
-
error,
|
|
75
|
-
});
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<Card>
|
|
80
|
-
{(appState !== "ready" || flowState.state === "parsing-url") && (
|
|
81
|
-
<Initial />
|
|
82
|
-
)}
|
|
83
|
-
{appState === "ready" && (
|
|
84
|
-
<>
|
|
85
|
-
{flowState.state === "progress" && (
|
|
86
|
-
<Progress
|
|
87
|
-
onSuccess={handleSuccess}
|
|
88
|
-
onError={handleError}
|
|
89
|
-
flowType={flowState.flowType}
|
|
90
|
-
/>
|
|
91
|
-
)}
|
|
92
|
-
{flowState.state === "no-challenges" && <Error type="warning" />}
|
|
93
|
-
{flowState.state === "success" && <Success />}
|
|
94
|
-
{flowState.state === "error" && <Error type="error" />}
|
|
95
|
-
</>
|
|
96
|
-
)}
|
|
97
|
-
</Card>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { publicVariables, theme } from "@slashid/react-primitives";
|
|
2
|
-
import { style } from "@vanilla-extract/css";
|
|
3
|
-
|
|
4
|
-
export const formInputs = style({
|
|
5
|
-
margin: "24px 0",
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
export const passwordRecoveryPrompt = style({
|
|
9
|
-
display: "flex",
|
|
10
|
-
alignItems: "baseline",
|
|
11
|
-
marginTop: "8px",
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export const errorMessage = style({
|
|
15
|
-
display: "block",
|
|
16
|
-
marginTop: theme.space[2],
|
|
17
|
-
color: publicVariables.color.error,
|
|
18
|
-
fontWeight: "600",
|
|
19
|
-
lineHeight: "122%",
|
|
20
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ensure that a valid Error instance is returned, since in JS you can throw anything.
|
|
3
|
-
*/
|
|
4
|
-
export function ensureError(value: unknown): Error {
|
|
5
|
-
if (value instanceof Error) return value;
|
|
6
|
-
|
|
7
|
-
let stringified = "[Unable to stringify the thrown value]";
|
|
8
|
-
try {
|
|
9
|
-
stringified = JSON.stringify(value);
|
|
10
|
-
} catch {
|
|
11
|
-
// ignore
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const error = new Error(
|
|
15
|
-
`This value was thrown as is, not through an Error: ${stringified}`
|
|
16
|
-
);
|
|
17
|
-
return error;
|
|
18
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Circle, Exclamation, Stack } from "@slashid/react-primitives";
|
|
2
|
-
import { Text } from "../text";
|
|
3
|
-
|
|
4
|
-
export type ErrorType = "warning" | "error";
|
|
5
|
-
|
|
6
|
-
function ErrorIcon({ type }: { type: ErrorType }) {
|
|
7
|
-
return (
|
|
8
|
-
<Circle variant={type === "warning" ? "blue" : "red"} shouldAnimate={false}>
|
|
9
|
-
<Exclamation />
|
|
10
|
-
</Circle>
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function Error({ type }: { type: ErrorType }) {
|
|
15
|
-
return (
|
|
16
|
-
<>
|
|
17
|
-
<Stack space="0.25">
|
|
18
|
-
<Text
|
|
19
|
-
as="h1"
|
|
20
|
-
variant={{ size: "2xl-title", weight: "bold" }}
|
|
21
|
-
t="error.title"
|
|
22
|
-
/>
|
|
23
|
-
<Text
|
|
24
|
-
as="h2"
|
|
25
|
-
t="error.detail"
|
|
26
|
-
variant={{ color: "contrast", weight: "semibold" }}
|
|
27
|
-
/>
|
|
28
|
-
</Stack>
|
|
29
|
-
<ErrorIcon type={type} />
|
|
30
|
-
</>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Skeleton, Stack } from "@slashid/react-primitives";
|
|
2
|
-
import { Loader } from "./flow.loader";
|
|
3
|
-
|
|
4
|
-
export function Initial() {
|
|
5
|
-
return (
|
|
6
|
-
<>
|
|
7
|
-
<Stack space="2">
|
|
8
|
-
<Skeleton width={"75%"} height={24} />
|
|
9
|
-
<Skeleton width={"50%"} height={16} />
|
|
10
|
-
</Stack>
|
|
11
|
-
<Loader />
|
|
12
|
-
</>
|
|
13
|
-
);
|
|
14
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import * as Sentry from "@sentry/react";
|
|
3
|
-
import { Stack } from "@slashid/react-primitives";
|
|
4
|
-
|
|
5
|
-
import { Loader } from "./flow.loader";
|
|
6
|
-
import type { FlowType } from "./flow.types";
|
|
7
|
-
import { Text } from "../text";
|
|
8
|
-
import { useAppContext } from "../app/app.context";
|
|
9
|
-
import { Recover } from "./flow.recover";
|
|
10
|
-
|
|
11
|
-
type SlashIDErrorMessage = { message: string };
|
|
12
|
-
class SlashIDError extends Error {
|
|
13
|
-
errors: SlashIDErrorMessage[];
|
|
14
|
-
|
|
15
|
-
constructor(errors: SlashIDErrorMessage[]) {
|
|
16
|
-
super(errors.length > 0 ? errors[0].message : "Unknown SlashID error");
|
|
17
|
-
this.errors = errors;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function isSlashIDError(e: unknown): e is SlashIDError {
|
|
22
|
-
if (
|
|
23
|
-
typeof e === "object" &&
|
|
24
|
-
e !== null &&
|
|
25
|
-
"errors" in e &&
|
|
26
|
-
Array.isArray(e.errors)
|
|
27
|
-
) {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function ensureError(value: unknown): Error {
|
|
35
|
-
if (value instanceof Error) return value;
|
|
36
|
-
|
|
37
|
-
// special case - sometimes the core SDK throws a non-error object
|
|
38
|
-
if (isSlashIDError(value)) {
|
|
39
|
-
const error = new SlashIDError(value.errors);
|
|
40
|
-
return error;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
let stringified = "[Unable to stringify the thrown value]";
|
|
44
|
-
try {
|
|
45
|
-
stringified = JSON.stringify(value);
|
|
46
|
-
} catch {
|
|
47
|
-
// ignore
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const error = new Error(
|
|
51
|
-
`This value was thrown as is, not through an Error: ${stringified}`
|
|
52
|
-
);
|
|
53
|
-
return error;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export type Props = {
|
|
57
|
-
flowType: FlowType;
|
|
58
|
-
onSuccess: () => void;
|
|
59
|
-
onError: ({ error }: { error: Error }) => void;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export function Progress({ onSuccess, onError, flowType }: Props) {
|
|
63
|
-
const { sdk } = useAppContext();
|
|
64
|
-
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
if (!sdk) return;
|
|
67
|
-
|
|
68
|
-
async function authenticate() {
|
|
69
|
-
try {
|
|
70
|
-
await sdk?.getUserFromURL();
|
|
71
|
-
onSuccess();
|
|
72
|
-
} catch (e: unknown) {
|
|
73
|
-
const safeError = ensureError(e);
|
|
74
|
-
Sentry.captureException(safeError);
|
|
75
|
-
onError({ error: safeError });
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function handlePasswordResetEvent() {
|
|
80
|
-
console.log("Password reset - input ready");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (flowType === "password-recovery") {
|
|
84
|
-
console.log("Subscribed");
|
|
85
|
-
sdk.subscribe("passwordResetReady", handlePasswordResetEvent);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
authenticate();
|
|
89
|
-
|
|
90
|
-
return () => {
|
|
91
|
-
if (flowType === "password-recovery") {
|
|
92
|
-
console.log("Cleaned up");
|
|
93
|
-
sdk.unsubscribe("passwordResetReady", handlePasswordResetEvent);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}, [flowType, onError, onSuccess, sdk]);
|
|
97
|
-
|
|
98
|
-
if (flowType === "password-recovery") {
|
|
99
|
-
return <Recover />;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return (
|
|
103
|
-
<>
|
|
104
|
-
<Stack space="0.25">
|
|
105
|
-
<Text
|
|
106
|
-
as="h1"
|
|
107
|
-
variant={{ size: "2xl-title", weight: "bold" }}
|
|
108
|
-
t="initial.title"
|
|
109
|
-
/>
|
|
110
|
-
<Text
|
|
111
|
-
variant={{ color: "contrast", weight: "semibold" }}
|
|
112
|
-
as="h2"
|
|
113
|
-
t="initial.details"
|
|
114
|
-
/>
|
|
115
|
-
</Stack>
|
|
116
|
-
<Loader />
|
|
117
|
-
</>
|
|
118
|
-
);
|
|
119
|
-
}
|