@kelpie/ui 0.4.1 → 0.5.1
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/api/resources/invites.d.ts +0 -2
- package/dist/api/resources/invites.d.ts.map +1 -1
- package/dist/api/resources/invites.js +5 -10
- package/dist/api/resources/invites.js.map +1 -1
- package/dist/api/resources/session.d.ts +17 -3
- package/dist/api/resources/session.d.ts.map +1 -1
- package/dist/api/resources/session.js +34 -6
- package/dist/api/resources/session.js.map +1 -1
- package/dist/app/KelpieApp.d.ts.map +1 -1
- package/dist/app/KelpieApp.js +3 -1
- package/dist/app/KelpieApp.js.map +1 -1
- package/dist/app/SessionGate.d.ts +6 -2
- package/dist/app/SessionGate.d.ts.map +1 -1
- package/dist/app/SessionGate.js +10 -3
- package/dist/app/SessionGate.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pages/auth/ForgotPasswordPage.js +2 -2
- package/dist/pages/auth/ForgotPasswordPage.js.map +1 -1
- package/dist/pages/auth/SignUpPage.d.ts +5 -3
- package/dist/pages/auth/SignUpPage.d.ts.map +1 -1
- package/dist/pages/auth/SignUpPage.js +12 -6
- package/dist/pages/auth/SignUpPage.js.map +1 -1
- package/dist/pages/auth/VerifyEmailConfirmPage.d.ts +9 -0
- package/dist/pages/auth/VerifyEmailConfirmPage.d.ts.map +1 -0
- package/dist/pages/auth/VerifyEmailConfirmPage.js +58 -0
- package/dist/pages/auth/VerifyEmailConfirmPage.js.map +1 -0
- package/dist/pages/auth/VerifyEmailPendingPage.d.ts +10 -0
- package/dist/pages/auth/VerifyEmailPendingPage.d.ts.map +1 -0
- package/dist/pages/auth/VerifyEmailPendingPage.js +35 -0
- package/dist/pages/auth/VerifyEmailPendingPage.js.map +1 -0
- package/package.json +2 -2
- package/src/api/resources/invites.ts +5 -15
- package/src/api/resources/session.ts +42 -6
- package/src/app/KelpieApp.tsx +7 -2
- package/src/app/SessionGate.tsx +11 -3
- package/src/index.ts +0 -1
- package/src/pages/auth/ForgotPasswordPage.tsx +2 -2
- package/src/pages/auth/SignUpPage.tsx +12 -6
- package/src/pages/auth/VerifyEmailConfirmPage.tsx +81 -0
- package/src/pages/auth/VerifyEmailPendingPage.tsx +65 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { InvitableRole, Invite } from '@kelpie/schemas';
|
|
2
2
|
import type { MutationResult } from '../resource.ts';
|
|
3
|
-
/** Where an invitee lands. `JoinPage` reads the token out of the query string. */
|
|
4
|
-
export declare function inviteUrlTemplate(origin: string): string;
|
|
5
3
|
export interface InviteListResult {
|
|
6
4
|
readonly invites: readonly Invite[];
|
|
7
5
|
readonly isLoading: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invites.d.ts","sourceRoot":"","sources":["../../../src/api/resources/invites.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAK5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"invites.d.ts","sourceRoot":"","sources":["../../../src/api/resources/invites.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAK5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAiBpD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAC7B;AAED,wBAAgB,UAAU,IAAI,gBAAgB,CAe7C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAC7B;AAED,wBAAgB,aAAa,IAAI,cAAc,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAkB3E;AAED,yFAAyF;AACzF,wBAAgB,eAAe,IAAI,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAchE;AAED,wBAAgB,eAAe,IAAI,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAa9D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createInviteBody, inviteSchema
|
|
1
|
+
import { createInviteBody, inviteSchema } from '@kelpie/schemas';
|
|
2
2
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
3
3
|
import { useApiClient } from '../context.js';
|
|
4
4
|
import { toError } from '../errors.js';
|
|
@@ -11,15 +11,10 @@ import { useSession } from './session.js';
|
|
|
11
11
|
* only renders this half for an admin, which keeps the refusal off screen
|
|
12
12
|
* without the browser being what decides it.
|
|
13
13
|
*
|
|
14
|
-
* The URL the emailed link points at is built
|
|
15
|
-
*
|
|
16
|
-
* the placeholder it fills in.
|
|
14
|
+
* The URL the emailed link points at is built server-side from the deployment's
|
|
15
|
+
* own base URL, so nothing here sends one.
|
|
17
16
|
*/
|
|
18
17
|
const INVITES_KEY = 'invites';
|
|
19
|
-
/** Where an invitee lands. `JoinPage` reads the token out of the query string. */
|
|
20
|
-
export function inviteUrlTemplate(origin) {
|
|
21
|
-
return `${origin}/join?token={token}`;
|
|
22
|
-
}
|
|
23
18
|
export function useInvites() {
|
|
24
19
|
const client = useApiClient();
|
|
25
20
|
const { session } = useSession();
|
|
@@ -41,7 +36,7 @@ export function useSendInvite() {
|
|
|
41
36
|
const { session } = useSession();
|
|
42
37
|
const workspaceId = session?.workspaceId ?? '';
|
|
43
38
|
const mutation = useMutation({
|
|
44
|
-
mutationFn: ({ email, role }) => client.post(`/workspaces/${workspaceId}/invites`, createInviteBody({ email, role
|
|
39
|
+
mutationFn: ({ email, role }) => client.post(`/workspaces/${workspaceId}/invites`, createInviteBody({ email, role }), inviteSchema.parse),
|
|
45
40
|
onSuccess: async () => {
|
|
46
41
|
await queryClient.invalidateQueries({ queryKey: [INVITES_KEY, workspaceId] });
|
|
47
42
|
},
|
|
@@ -55,7 +50,7 @@ export function useResendInvite() {
|
|
|
55
50
|
const { session } = useSession();
|
|
56
51
|
const workspaceId = session?.workspaceId ?? '';
|
|
57
52
|
const mutation = useMutation({
|
|
58
|
-
mutationFn: (inviteId) => client.post(`/workspaces/${workspaceId}/invites/${inviteId}/resend`,
|
|
53
|
+
mutationFn: (inviteId) => client.post(`/workspaces/${workspaceId}/invites/${inviteId}/resend`, {}, inviteSchema.parse),
|
|
59
54
|
onSuccess: async () => {
|
|
60
55
|
await queryClient.invalidateQueries({ queryKey: [INVITES_KEY, workspaceId] });
|
|
61
56
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invites.js","sourceRoot":"","sources":["../../../src/api/resources/invites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"invites.js","sourceRoot":"","sources":["../../../src/api/resources/invites.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConfirmPasswordResetInput, CreateWorkspaceInput, LogInInput, RequestPasswordResetInput, Session, SignUpInput, SignedInAccount, Workspace } from '@kelpie/schemas';
|
|
1
|
+
import type { ConfirmEmailVerificationInput, ConfirmPasswordResetInput, CreateWorkspaceInput, LogInInput, RequestPasswordResetInput, Session, SignUpInput, SignedInAccount, Workspace } from '@kelpie/schemas';
|
|
2
2
|
import type { MutationResult } from '../resource.ts';
|
|
3
3
|
export interface SessionState {
|
|
4
4
|
readonly session: Session | undefined;
|
|
@@ -7,6 +7,8 @@ export interface SessionState {
|
|
|
7
7
|
readonly isSignedOut: boolean;
|
|
8
8
|
/** Signed in, but the account has no workspace yet. Every CRM endpoint answers `403` until it does. */
|
|
9
9
|
readonly needsWorkspace: boolean;
|
|
10
|
+
/** No workspace yet, and creating one will answer `403` until the account verifies its email. */
|
|
11
|
+
readonly needsEmailVerification: boolean;
|
|
10
12
|
readonly error: Error | null;
|
|
11
13
|
}
|
|
12
14
|
export declare function useSession(): SessionState;
|
|
@@ -20,8 +22,6 @@ export declare function useLogIn(): MutationResult<LogInInput, SignedInAccount>;
|
|
|
20
22
|
*/
|
|
21
23
|
export declare function useSignUp(): MutationResult<SignUpInput, SignedInAccount>;
|
|
22
24
|
export declare function useLogOut(): MutationResult<void, void>;
|
|
23
|
-
/** Where a reset email lands. `ResetPasswordPage` reads the token out of the query string. */
|
|
24
|
-
export declare function resetUrlTemplate(origin: string): string;
|
|
25
25
|
/**
|
|
26
26
|
* Asks for a reset link.
|
|
27
27
|
*
|
|
@@ -39,6 +39,20 @@ export declare function useRequestPasswordReset(): MutationResult<RequestPasswor
|
|
|
39
39
|
* caller sends the reader to sign in rather than into the app.
|
|
40
40
|
*/
|
|
41
41
|
export declare function useConfirmPasswordReset(): MutationResult<ConfirmPasswordResetInput, void>;
|
|
42
|
+
/**
|
|
43
|
+
* Asks for a fresh verification link. The same call a "resend" button makes,
|
|
44
|
+
* and a no-op once the account is already verified.
|
|
45
|
+
*
|
|
46
|
+
* Nothing in the cache changes: this signs nobody in or out.
|
|
47
|
+
*/
|
|
48
|
+
export declare function useRequestEmailVerification(): MutationResult<void, void>;
|
|
49
|
+
/**
|
|
50
|
+
* Spends a verification token from that email.
|
|
51
|
+
*
|
|
52
|
+
* Unlike a password reset this ends no session, so the caller only needs the
|
|
53
|
+
* session re-read: `needsEmailVerification` flips once it lands.
|
|
54
|
+
*/
|
|
55
|
+
export declare function useConfirmEmailVerification(): MutationResult<ConfirmEmailVerificationInput, void>;
|
|
42
56
|
/**
|
|
43
57
|
* Joins the workspace an invitation names.
|
|
44
58
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/api/resources/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/api/resources/session.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,6BAA6B,EAC7B,yBAAyB,EACzB,oBAAoB,EACpB,UAAU,EACV,yBAAyB,EACzB,OAAO,EACP,WAAW,EACX,eAAe,EACf,SAAS,EACV,MAAM,iBAAiB,CAAA;AAOxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAgCpD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,uGAAuG;IACvG,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC,iGAAiG;IACjG,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAA;IACxC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAC7B;AAED,wBAAgB,UAAU,IAAI,YAAY,CAczC;AAED,wBAAgB,QAAQ,IAAI,cAAc,CAAC,UAAU,EAAE,eAAe,CAAC,CAatE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,IAAI,cAAc,CAAC,WAAW,EAAE,eAAe,CAAC,CAaxE;AAED,wBAAgB,SAAS,IAAI,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAatD;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,IAAI,cAAc,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAQzF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,cAAc,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAYzF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAOxE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CAAC,6BAA6B,EAAE,IAAI,CAAC,CAYjG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,cAAc,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,CAAC,CAavF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAapF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { confirmPasswordResetBody, createWorkspaceBody, logInBody, requestPasswordResetBody, sessionSchema, signUpBody, signedInAccountSchema, workspaceSchema, } from '@kelpie/schemas';
|
|
1
|
+
import { confirmEmailVerificationBody, confirmPasswordResetBody, createWorkspaceBody, logInBody, requestPasswordResetBody, sessionSchema, signUpBody, signedInAccountSchema, workspaceSchema, } from '@kelpie/schemas';
|
|
2
2
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
3
3
|
import { ApiError } from '../client.js';
|
|
4
4
|
import { useApiClient } from '../context.js';
|
|
@@ -29,11 +29,13 @@ export function useSession() {
|
|
|
29
29
|
const client = useApiClient();
|
|
30
30
|
const result = useQuery(sessionQuery(client));
|
|
31
31
|
const isSignedOut = result.error instanceof ApiError && result.error.status === 401;
|
|
32
|
+
const needsWorkspace = result.data !== undefined && result.data.workspaceId === null;
|
|
32
33
|
return {
|
|
33
34
|
session: result.data,
|
|
34
35
|
isLoading: result.isPending,
|
|
35
36
|
isSignedOut,
|
|
36
|
-
needsWorkspace
|
|
37
|
+
needsWorkspace,
|
|
38
|
+
needsEmailVerification: needsWorkspace && result.data?.emailVerified === false,
|
|
37
39
|
error: isSignedOut ? null : toError(result.error),
|
|
38
40
|
};
|
|
39
41
|
}
|
|
@@ -81,10 +83,6 @@ export function useLogOut() {
|
|
|
81
83
|
});
|
|
82
84
|
return asMutationResult(mutation);
|
|
83
85
|
}
|
|
84
|
-
/** Where a reset email lands. `ResetPasswordPage` reads the token out of the query string. */
|
|
85
|
-
export function resetUrlTemplate(origin) {
|
|
86
|
-
return `${origin}/reset-password?token={token}`;
|
|
87
|
-
}
|
|
88
86
|
/**
|
|
89
87
|
* Asks for a reset link.
|
|
90
88
|
*
|
|
@@ -118,6 +116,36 @@ export function useConfirmPasswordReset() {
|
|
|
118
116
|
});
|
|
119
117
|
return asMutationResult(mutation);
|
|
120
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Asks for a fresh verification link. The same call a "resend" button makes,
|
|
121
|
+
* and a no-op once the account is already verified.
|
|
122
|
+
*
|
|
123
|
+
* Nothing in the cache changes: this signs nobody in or out.
|
|
124
|
+
*/
|
|
125
|
+
export function useRequestEmailVerification() {
|
|
126
|
+
const client = useApiClient();
|
|
127
|
+
const mutation = useMutation({
|
|
128
|
+
mutationFn: () => client.postEmpty('/auth/verify-email'),
|
|
129
|
+
});
|
|
130
|
+
return asMutationResult(mutation);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Spends a verification token from that email.
|
|
134
|
+
*
|
|
135
|
+
* Unlike a password reset this ends no session, so the caller only needs the
|
|
136
|
+
* session re-read: `needsEmailVerification` flips once it lands.
|
|
137
|
+
*/
|
|
138
|
+
export function useConfirmEmailVerification() {
|
|
139
|
+
const client = useApiClient();
|
|
140
|
+
const queryClient = useQueryClient();
|
|
141
|
+
const mutation = useMutation({
|
|
142
|
+
mutationFn: (input) => client.postEmpty('/auth/verify-email/confirm', confirmEmailVerificationBody(input)),
|
|
143
|
+
onSuccess: async () => {
|
|
144
|
+
await queryClient.fetchQuery(sessionQuery(client));
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
return asMutationResult(mutation);
|
|
148
|
+
}
|
|
121
149
|
/**
|
|
122
150
|
* Joins the workspace an invitation names.
|
|
123
151
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/api/resources/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,SAAS,EACT,wBAAwB,EACxB,aAAa,EACb,UAAU,EACV,qBAAqB,EACrB,eAAe,GAChB,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/api/resources/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KelpieApp.d.ts","sourceRoot":"","sources":["../../src/app/KelpieApp.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"KelpieApp.d.ts","sourceRoot":"","sources":["../../src/app/KelpieApp.tsx"],"names":[],"mappings":"AAuDA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAG3D;;;;;;;;;GASG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAA;IACjC,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAUpF"}
|
package/dist/app/KelpieApp.js
CHANGED
|
@@ -43,6 +43,8 @@ import { JoinPage } from '../pages/auth/JoinPage.js';
|
|
|
43
43
|
import { ResetPasswordPage } from '../pages/auth/ResetPasswordPage.js';
|
|
44
44
|
import { SignInPage } from '../pages/auth/SignInPage.js';
|
|
45
45
|
import { SignUpPage } from '../pages/auth/SignUpPage.js';
|
|
46
|
+
import { VerifyEmailConfirmPage } from '../pages/auth/VerifyEmailConfirmPage.js';
|
|
47
|
+
import { VerifyEmailPendingPage } from '../pages/auth/VerifyEmailPendingPage.js';
|
|
46
48
|
import { DashboardPage } from '../pages/dashboard/DashboardPage.js';
|
|
47
49
|
import { HandbookLayout } from '../pages/handbook/HandbookPage.js';
|
|
48
50
|
import { HandbookStepPage } from '../pages/onboarding/HandbookStepPage.js';
|
|
@@ -71,6 +73,6 @@ function AppRoutes() {
|
|
|
71
73
|
const moduleRoutes = useModuleRoutes();
|
|
72
74
|
const accountRoutes = moduleRoutes.filter(isAccountRoute);
|
|
73
75
|
const shellRoutes = moduleRoutes.filter((route) => !isAccountRoute(route));
|
|
74
|
-
return (_jsxs(Routes, { children: [_jsx(Route, { path: "/login", element: _jsx(SignInPage, {}) }), _jsx(Route, { path: "/signup", element: _jsx(SignUpPage, {}) }), _jsx(Route, { path: "/forgot-password", element: _jsx(ForgotPasswordPage, {}) }), _jsx(Route, { path: "/reset-password", element: _jsx(ResetPasswordPage, {}) }), _jsx(Route, { path: "/join", element: _jsx(JoinPage, {}) }), _jsx(Route, { path: "/onboarding/workspace", element: _jsx(WorkspaceStepPage, {}) }), _jsxs(Route, { element: _jsx(SessionGate, {}), children: [_jsx(Route, { path: "/onboarding/invites", element: _jsx(InvitesStepPage, {}) }), _jsx(Route, { path: "/onboarding/handbook", element: _jsx(HandbookStepPage, {}) }), _jsxs(Route, { element: _jsx(Shell, {}), children: [_jsx(Route, { index: true, element: _jsx(Navigate, { to: "/dashboard", replace: true }) }), _jsx(Route, { path: "dashboard", element: _jsx(DashboardPage, {}) }), _jsx(Route, { path: "search", element: _jsx(SearchPage, {}) }), _jsx(Route, { path: "people", element: _jsx(PeoplePage, {}) }), _jsx(Route, { path: "people/:id", element: _jsx(PersonDetail, {}) }), _jsx(Route, { path: "hiring", element: _jsx(HiringPage, {}) }), _jsx(Route, { path: "hiring/:id", element: _jsx(RoleDetail, {}) }), _jsx(Route, { path: "companies", element: _jsx(CompaniesPage, {}) }), _jsx(Route, { path: "companies/:id", element: _jsx(CompanyDetail, {}) }), _jsx(Route, { path: "deals", element: _jsx(DealsPage, {}) }), _jsx(Route, { path: "deals/settings", element: _jsx(DealStageSettingsPage, {}) }), _jsx(Route, { path: "deals/:id", element: _jsx(DealDetail, {}) }), _jsx(Route, { path: "opportunities", element: _jsx(OpportunitiesPage, {}) }), _jsx(Route, { path: "opportunities/settings", element: _jsx(OpportunityStageSettingsPage, {}) }), _jsx(Route, { path: "opportunities/:id", element: _jsx(OpportunityDetail, {}) }), _jsx(Route, { path: "fundraising", element: _jsx(FundraisingPage, {}) }), _jsx(Route, { path: "fundraising/settings", element: _jsx(RaiseStageSettingsPage, {}) }), _jsx(Route, { path: "fundraising/:id", element: _jsx(RaiseDetail, {}) }), _jsx(Route, { path: "partnerships", element: _jsx(PartnershipsPage, {}) }), _jsx(Route, { path: "partnerships/settings", element: _jsx(PartnershipStageSettingsPage, {}) }), _jsx(Route, { path: "partnerships/:id", element: _jsx(PartnershipDetail, {}) }), _jsx(Route, { path: "planning", element: _jsx(PlanningPage, {}) }), _jsx(Route, { path: "decisions", element: _jsx(DecisionsPage, {}) }), _jsx(Route, { path: "forms", element: _jsx(FormsPage, {}) }), _jsx(Route, { path: "forms/:id", element: _jsx(FormDetail, {}) }), _jsx(Route, { path: "handbook", element: _jsx(HandbookLayout, {}) }), _jsx(Route, { path: "handbook/:pageId", element: _jsx(HandbookLayout, {}) }), _jsx(Route, { path: "admin/workspace", element: _jsx(WorkspaceSettingsPage, {}) }), _jsx(Route, { path: "admin/team", element: _jsx(TeamPage, {}) }), _jsx(Route, { path: "admin/data", element: _jsx(DataPage, {}) }), _jsx(Route, { path: "admin/api-keys", element: _jsx(ApiKeysPage, {}) }), _jsx(Route, { path: "admin/mcp", element: _jsx(McpPage, {}) }), _jsx(Route, { path: "admin/webhooks", element: _jsx(WebhooksPage, {}) }), _jsx(Route, { path: "admin/modules", element: _jsx(ModulesPage, {}) }), _jsxs(Route, { path: "account", element: _jsx(AccountLayout, {}), children: [_jsx(Route, { index: true, element: _jsx(Navigate, { to: "/account/profile", replace: true }) }), _jsx(Route, { path: "profile", element: _jsx(ProfilePage, {}) }), _jsx(Route, { path: "security", element: _jsx(SecurityPage, {}) }), _jsx(Route, { path: "preferences", element: _jsx(PreferencesPage, {}) }), _jsx(Route, { path: "api-keys", element: _jsx(PersonalApiKeysPage, {}) }), accountRoutes.map((route) => (_jsx(Route, { path: route.path.slice(ACCOUNT_PREFIX.length), element: route.element }, route.path)))] }), shellRoutes.map((route) => (_jsx(Route, { path: route.path, element: route.element }, route.path))), _jsx(Route, { path: "*", element: _jsx(NotFoundPage, {}) })] })] })] }));
|
|
76
|
+
return (_jsxs(Routes, { children: [_jsx(Route, { path: "/login", element: _jsx(SignInPage, {}) }), _jsx(Route, { path: "/signup", element: _jsx(SignUpPage, {}) }), _jsx(Route, { path: "/forgot-password", element: _jsx(ForgotPasswordPage, {}) }), _jsx(Route, { path: "/reset-password", element: _jsx(ResetPasswordPage, {}) }), _jsx(Route, { path: "/join", element: _jsx(JoinPage, {}) }), _jsx(Route, { path: "/onboarding/workspace", element: _jsx(WorkspaceStepPage, {}) }), _jsx(Route, { path: "/verify-email", element: _jsx(VerifyEmailConfirmPage, {}) }), _jsx(Route, { path: "/verify-email/pending", element: _jsx(VerifyEmailPendingPage, {}) }), _jsxs(Route, { element: _jsx(SessionGate, {}), children: [_jsx(Route, { path: "/onboarding/invites", element: _jsx(InvitesStepPage, {}) }), _jsx(Route, { path: "/onboarding/handbook", element: _jsx(HandbookStepPage, {}) }), _jsxs(Route, { element: _jsx(Shell, {}), children: [_jsx(Route, { index: true, element: _jsx(Navigate, { to: "/dashboard", replace: true }) }), _jsx(Route, { path: "dashboard", element: _jsx(DashboardPage, {}) }), _jsx(Route, { path: "search", element: _jsx(SearchPage, {}) }), _jsx(Route, { path: "people", element: _jsx(PeoplePage, {}) }), _jsx(Route, { path: "people/:id", element: _jsx(PersonDetail, {}) }), _jsx(Route, { path: "hiring", element: _jsx(HiringPage, {}) }), _jsx(Route, { path: "hiring/:id", element: _jsx(RoleDetail, {}) }), _jsx(Route, { path: "companies", element: _jsx(CompaniesPage, {}) }), _jsx(Route, { path: "companies/:id", element: _jsx(CompanyDetail, {}) }), _jsx(Route, { path: "deals", element: _jsx(DealsPage, {}) }), _jsx(Route, { path: "deals/settings", element: _jsx(DealStageSettingsPage, {}) }), _jsx(Route, { path: "deals/:id", element: _jsx(DealDetail, {}) }), _jsx(Route, { path: "opportunities", element: _jsx(OpportunitiesPage, {}) }), _jsx(Route, { path: "opportunities/settings", element: _jsx(OpportunityStageSettingsPage, {}) }), _jsx(Route, { path: "opportunities/:id", element: _jsx(OpportunityDetail, {}) }), _jsx(Route, { path: "fundraising", element: _jsx(FundraisingPage, {}) }), _jsx(Route, { path: "fundraising/settings", element: _jsx(RaiseStageSettingsPage, {}) }), _jsx(Route, { path: "fundraising/:id", element: _jsx(RaiseDetail, {}) }), _jsx(Route, { path: "partnerships", element: _jsx(PartnershipsPage, {}) }), _jsx(Route, { path: "partnerships/settings", element: _jsx(PartnershipStageSettingsPage, {}) }), _jsx(Route, { path: "partnerships/:id", element: _jsx(PartnershipDetail, {}) }), _jsx(Route, { path: "planning", element: _jsx(PlanningPage, {}) }), _jsx(Route, { path: "decisions", element: _jsx(DecisionsPage, {}) }), _jsx(Route, { path: "forms", element: _jsx(FormsPage, {}) }), _jsx(Route, { path: "forms/:id", element: _jsx(FormDetail, {}) }), _jsx(Route, { path: "handbook", element: _jsx(HandbookLayout, {}) }), _jsx(Route, { path: "handbook/:pageId", element: _jsx(HandbookLayout, {}) }), _jsx(Route, { path: "admin/workspace", element: _jsx(WorkspaceSettingsPage, {}) }), _jsx(Route, { path: "admin/team", element: _jsx(TeamPage, {}) }), _jsx(Route, { path: "admin/data", element: _jsx(DataPage, {}) }), _jsx(Route, { path: "admin/api-keys", element: _jsx(ApiKeysPage, {}) }), _jsx(Route, { path: "admin/mcp", element: _jsx(McpPage, {}) }), _jsx(Route, { path: "admin/webhooks", element: _jsx(WebhooksPage, {}) }), _jsx(Route, { path: "admin/modules", element: _jsx(ModulesPage, {}) }), _jsxs(Route, { path: "account", element: _jsx(AccountLayout, {}), children: [_jsx(Route, { index: true, element: _jsx(Navigate, { to: "/account/profile", replace: true }) }), _jsx(Route, { path: "profile", element: _jsx(ProfilePage, {}) }), _jsx(Route, { path: "security", element: _jsx(SecurityPage, {}) }), _jsx(Route, { path: "preferences", element: _jsx(PreferencesPage, {}) }), _jsx(Route, { path: "api-keys", element: _jsx(PersonalApiKeysPage, {}) }), accountRoutes.map((route) => (_jsx(Route, { path: route.path.slice(ACCOUNT_PREFIX.length), element: route.element }, route.path)))] }), shellRoutes.map((route) => (_jsx(Route, { path: route.path, element: route.element }, route.path))), _jsx(Route, { path: "*", element: _jsx(NotFoundPage, {}) })] })] })] }));
|
|
75
77
|
}
|
|
76
78
|
//# sourceMappingURL=KelpieApp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KelpieApp.js","sourceRoot":"","sources":["../../src/app/KelpieApp.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"KelpieApp.js","sourceRoot":"","sources":["../../src/app/KelpieApp.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What stands between a URL and a page that needs a workspace.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Four answers, and they are not the same thing:
|
|
5
5
|
*
|
|
6
6
|
* - `401` means sign in. That is a redirect.
|
|
7
|
-
* - Signed in
|
|
7
|
+
* - Signed in, no workspace, email unverified means go verify it: creating a
|
|
8
|
+
* workspace answers `403` until then. Checked before `needsWorkspace`,
|
|
9
|
+
* since both are true at once for a fresh direct signup and this is the one
|
|
10
|
+
* that has to happen first.
|
|
11
|
+
* - Signed in, no workspace, verified means create one. Also a redirect, to a
|
|
8
12
|
* different place, because sending someone to a sign-in form they have
|
|
9
13
|
* already passed is a loop.
|
|
10
14
|
* - Anything else is the service being unreachable or broken, and redirecting
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionGate.d.ts","sourceRoot":"","sources":["../../src/app/SessionGate.tsx"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"SessionGate.d.ts","sourceRoot":"","sources":["../../src/app/SessionGate.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CA4B/C"}
|
package/dist/app/SessionGate.js
CHANGED
|
@@ -5,17 +5,21 @@ import { ErrorPanel, LoadingPanel } from '../components/QueryState.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* What stands between a URL and a page that needs a workspace.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Four answers, and they are not the same thing:
|
|
9
9
|
*
|
|
10
10
|
* - `401` means sign in. That is a redirect.
|
|
11
|
-
* - Signed in
|
|
11
|
+
* - Signed in, no workspace, email unverified means go verify it: creating a
|
|
12
|
+
* workspace answers `403` until then. Checked before `needsWorkspace`,
|
|
13
|
+
* since both are true at once for a fresh direct signup and this is the one
|
|
14
|
+
* that has to happen first.
|
|
15
|
+
* - Signed in, no workspace, verified means create one. Also a redirect, to a
|
|
12
16
|
* different place, because sending someone to a sign-in form they have
|
|
13
17
|
* already passed is a loop.
|
|
14
18
|
* - Anything else is the service being unreachable or broken, and redirecting
|
|
15
19
|
* on that would hide it behind a sign-in form that will also fail.
|
|
16
20
|
*/
|
|
17
21
|
export function SessionGate() {
|
|
18
|
-
const { isLoading, isSignedOut, needsWorkspace, error } = useSession();
|
|
22
|
+
const { isLoading, isSignedOut, needsWorkspace, needsEmailVerification, error } = useSession();
|
|
19
23
|
if (isSignedOut) {
|
|
20
24
|
return _jsx(Navigate, { to: "/login", replace: true });
|
|
21
25
|
}
|
|
@@ -25,6 +29,9 @@ export function SessionGate() {
|
|
|
25
29
|
if (isLoading) {
|
|
26
30
|
return _jsx(LoadingPanel, {});
|
|
27
31
|
}
|
|
32
|
+
if (needsEmailVerification) {
|
|
33
|
+
return _jsx(Navigate, { to: "/verify-email/pending", replace: true });
|
|
34
|
+
}
|
|
28
35
|
if (needsWorkspace) {
|
|
29
36
|
return _jsx(Navigate, { to: "/onboarding/workspace", replace: true });
|
|
30
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionGate.js","sourceRoot":"","sources":["../../src/app/SessionGate.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,6BAA8B,CAAA;AAEvE
|
|
1
|
+
{"version":3,"file":"SessionGate.js","sourceRoot":"","sources":["../../src/app/SessionGate.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,6BAA8B,CAAA;AAEvE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,sBAAsB,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,CAAA;IAE9F,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,KAAC,QAAQ,IAAC,EAAE,EAAC,QAAQ,EAAC,OAAO,SAAG,CAAA;IACzC,CAAC;IAED,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,CACL,cAAK,SAAS,EAAC,6BAA6B,YAC1C,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,GACxB,CACP,CAAA;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,KAAC,YAAY,KAAG,CAAA;IACzB,CAAC;IAED,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO,KAAC,QAAQ,IAAC,EAAE,EAAC,uBAAuB,EAAC,OAAO,SAAG,CAAA;IACxD,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,KAAC,QAAQ,IAAC,EAAE,EAAC,uBAAuB,EAAC,OAAO,SAAG,CAAA;IACxD,CAAC;IAED,OAAO,KAAC,MAAM,KAAG,CAAA;AACnB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export { MAX_PAGE_SIZE, useCreatePlanItem, useDeletePlanItem, usePlanItems, useP
|
|
|
21
21
|
export type { PlanItemFilters } from './api/resources/planItems.ts';
|
|
22
22
|
export { useCreateDecision, useDecisions, useDeleteDecision, useUpdateDecision, } from './api/resources/decisions.ts';
|
|
23
23
|
export type { DecisionFilters } from './api/resources/decisions.ts';
|
|
24
|
-
export {
|
|
24
|
+
export { useAcceptInvite, useConfirmPasswordReset, useCreateWorkspace, useLogIn, useLogOut, useRequestPasswordReset, useSession, useSignUp, } from './api/resources/session.ts';
|
|
25
25
|
export type { SessionState } from './api/resources/session.ts';
|
|
26
26
|
export { fetchServiceHealth } from './api/health.ts';
|
|
27
27
|
export type { HealthRequestOptions, ServiceHealth } from './api/health.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE7D,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC3D,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE/G,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAEtF,OAAO,EACL,eAAe,EACf,eAAe,EACf,SAAS,EACT,SAAS,EACT,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEjF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAExF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAEnE,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAEnE,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE7D,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC3D,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE/G,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAEtF,OAAO,EACL,eAAe,EACf,eAAe,EACf,SAAS,EACT,SAAS,EACT,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEjF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAExF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAEnE,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAEnE,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,uBAAuB,EACvB,UAAU,EACV,SAAS,GACV,MAAM,4BAA4B,CAAA;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAChE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACnE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AACpF,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AACrF,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AACvF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACzE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACxF,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAA;AAC1E,YAAY,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAA;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAA;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAE5E,OAAO,EACL,WAAW,EACX,OAAO,EACP,eAAe,EACf,YAAY,EACZ,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,WAAW,EAAE,aAAa,IAAI,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEvF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC3G,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAChF,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,OAAO,EACP,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,SAAS,EACT,iBAAiB,GAClB,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAE5D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AACrG,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAErF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,eAAe,GAChB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { useCreatePerson, useDeletePerson, usePeople, usePerson, useUpdatePerson
|
|
|
11
11
|
export { useCreatePosition, useDeletePosition, usePositions, useUpdatePositionTitle, } from './api/resources/positions.js';
|
|
12
12
|
export { MAX_PAGE_SIZE, useCreatePlanItem, useDeletePlanItem, usePlanItems, usePlanItemsForRecords, useRecordPlanItems, useUpdatePlanItem, } from './api/resources/planItems.js';
|
|
13
13
|
export { useCreateDecision, useDecisions, useDeleteDecision, useUpdateDecision, } from './api/resources/decisions.js';
|
|
14
|
-
export {
|
|
14
|
+
export { useAcceptInvite, useConfirmPasswordReset, useCreateWorkspace, useLogIn, useLogOut, useRequestPasswordReset, useSession, useSignUp, } from './api/resources/session.js';
|
|
15
15
|
export { fetchServiceHealth } from './api/health.js';
|
|
16
16
|
export { AgentTasks } from './components/AgentTasks.js';
|
|
17
17
|
export { Chip } from './components/Chip.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAqB,CAAA;AAG/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAqB,CAAA;AAGnD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAuB,CAAA;AAGnD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAWvD,OAAO,EACL,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EACL,eAAe,EACf,eAAe,EACf,SAAS,EACT,SAAS,EACT,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAGlC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Link } from 'react-router';
|
|
4
|
-
import {
|
|
4
|
+
import { useRequestPasswordReset } from '../../api/resources/session.js';
|
|
5
5
|
import { ErrorPanel } from '../../components/QueryState.js';
|
|
6
6
|
import { SubmitButton, TextField } from './AuthForm.js';
|
|
7
7
|
import { AuthLayout } from './AuthLayout.js';
|
|
@@ -24,7 +24,7 @@ export function ForgotPasswordPage() {
|
|
|
24
24
|
event.preventDefault();
|
|
25
25
|
const address = email.trim();
|
|
26
26
|
request
|
|
27
|
-
.runAsync({ email: address
|
|
27
|
+
.runAsync({ email: address })
|
|
28
28
|
.then(() => {
|
|
29
29
|
setSentTo(address);
|
|
30
30
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForgotPasswordPage.js","sourceRoot":"","sources":["../../../src/pages/auth/ForgotPasswordPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAEnC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ForgotPasswordPage.js","sourceRoot":"","sources":["../../../src/pages/auth/ForgotPasswordPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAEnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAiC,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAgB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,OAAO,GAAG,uBAAuB,EAAE,CAAA;IACzC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAEzD,SAAS,MAAM,CAAC,KAAgB;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAA;QAEtB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QAE5B,OAAO;aACJ,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;aAC5B,IAAI,CAAC,GAAG,EAAE;YACT,SAAS,CAAC,OAAO,CAAC,CAAA;QACpB,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,MAAM,YAAY,GAAG,CACnB,KAAC,IAAI,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAC,yCAAyC,gCAE9D,CACR,CAAA;IAED,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,CACL,KAAC,UAAU,IAAC,KAAK,EAAC,kBAAkB,EAAC,MAAM,EAAE,YAAY,YACvD,aAAG,SAAS,EAAC,iCAAiC,0CACnB,eAAM,SAAS,EAAC,sBAAsB,YAAE,MAAM,GAAQ,uEAE7E,GACO,CACd,CAAA;IACH,CAAC;IAED,OAAO,CACL,KAAC,UAAU,IACT,KAAK,EAAC,gBAAgB,EACtB,WAAW,EAAC,+CAA+C,EAC3D,MAAM,EAAE,YAAY,YAEpB,gBAAM,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,gBAAgB,aAChD,KAAC,SAAS,IACR,KAAK,EAAC,OAAO,EACb,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAC,OAAO,EACpB,QAAQ,SACR,EACD,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,KAAC,UAAU,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,GAAI,EAC/D,KAAC,YAAY,IACX,KAAK,EAAC,iBAAiB,EACvB,YAAY,EAAC,eAAU,EACvB,SAAS,EAAE,OAAO,CAAC,SAAS,GAC5B,IACG,GACI,CACd,CAAA;AACH,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Creating an account, against `POST /v1/auth/signup`.
|
|
3
3
|
*
|
|
4
|
-
* Signup makes the user and nothing else, per `onboarding.md`, so success
|
|
5
|
-
* on the
|
|
6
|
-
*
|
|
4
|
+
* Signup makes the user and nothing else, per `onboarding.md`, so success
|
|
5
|
+
* lands on the email-verification screen rather than in the app or the first
|
|
6
|
+
* onboarding step: the account cannot create a workspace until it verifies.
|
|
7
|
+
* The response sets the session cookie, which is why that next page can
|
|
8
|
+
* already act as the signed-in account.
|
|
7
9
|
*
|
|
8
10
|
* The mockup collected this into `sessionStorage` and committed the lot at the
|
|
9
11
|
* end of the wizard. Here each step commits as it is finished: a draft account
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignUpPage.d.ts","sourceRoot":"","sources":["../../../src/pages/auth/SignUpPage.tsx"],"names":[],"mappings":"AAUA
|
|
1
|
+
{"version":3,"file":"SignUpPage.d.ts","sourceRoot":"","sources":["../../../src/pages/auth/SignUpPage.tsx"],"names":[],"mappings":"AAUA;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CA2E9C"}
|
|
@@ -9,9 +9,11 @@ import { AuthLayout } from './AuthLayout.js';
|
|
|
9
9
|
/**
|
|
10
10
|
* Creating an account, against `POST /v1/auth/signup`.
|
|
11
11
|
*
|
|
12
|
-
* Signup makes the user and nothing else, per `onboarding.md`, so success
|
|
13
|
-
* on the
|
|
14
|
-
*
|
|
12
|
+
* Signup makes the user and nothing else, per `onboarding.md`, so success
|
|
13
|
+
* lands on the email-verification screen rather than in the app or the first
|
|
14
|
+
* onboarding step: the account cannot create a workspace until it verifies.
|
|
15
|
+
* The response sets the session cookie, which is why that next page can
|
|
16
|
+
* already act as the signed-in account.
|
|
15
17
|
*
|
|
16
18
|
* The mockup collected this into `sessionStorage` and committed the lot at the
|
|
17
19
|
* end of the wizard. Here each step commits as it is finished: a draft account
|
|
@@ -34,10 +36,14 @@ export function SignUpPage() {
|
|
|
34
36
|
}
|
|
35
37
|
setLocalError(null);
|
|
36
38
|
signUp
|
|
37
|
-
.runAsync({
|
|
38
|
-
.
|
|
39
|
+
.runAsync({
|
|
40
|
+
name: name.trim(),
|
|
41
|
+
email: email.trim(),
|
|
42
|
+
password,
|
|
43
|
+
})
|
|
44
|
+
.then(() => navigate('/verify-email/pending', { replace: true }))
|
|
39
45
|
.catch(() => undefined);
|
|
40
46
|
}
|
|
41
|
-
return (_jsx(AuthLayout, { title: "Create account", description: "Next you will create a workspace for your company.", footer: _jsxs("span", { className: "text-ink-muted", children: ["Already have an account?", ' ', _jsx(Link, { to: "/login", className: "font-medium text-accent hover:underline", children: "Sign in" })] }), children: _jsxs("form", { onSubmit: submit, className: "mt-5 space-y-3", children: [_jsx(TextField, { label: "Your name", value: name, onChange: setName, autoComplete: "name", required: true }), _jsx(TextField, { label: "Email", type: "email", value: email, onChange: setEmail, autoComplete: "email", required: true }), _jsx(TextField, { label: "Password", type: "password", value: password, onChange: setPassword, autoComplete: "new-password", hint: `At least ${String(MINIMUM_PASSWORD_LENGTH)} characters.`, required: true }), localError !== null && _jsx("p", { className: "text-[12px] text-danger", children: localError }), signUp.error !== null && _jsx(ErrorPanel, { error: signUp.error }), _jsx(SubmitButton, { label: "Continue", pendingLabel: "Creating\u2026", isPending: signUp.isPending })] }) }));
|
|
47
|
+
return (_jsx(AuthLayout, { title: "Create account", description: "Next you will verify your email, then create a workspace for your company.", footer: _jsxs("span", { className: "text-ink-muted", children: ["Already have an account?", ' ', _jsx(Link, { to: "/login", className: "font-medium text-accent hover:underline", children: "Sign in" })] }), children: _jsxs("form", { onSubmit: submit, className: "mt-5 space-y-3", children: [_jsx(TextField, { label: "Your name", value: name, onChange: setName, autoComplete: "name", required: true }), _jsx(TextField, { label: "Email", type: "email", value: email, onChange: setEmail, autoComplete: "email", required: true }), _jsx(TextField, { label: "Password", type: "password", value: password, onChange: setPassword, autoComplete: "new-password", hint: `At least ${String(MINIMUM_PASSWORD_LENGTH)} characters.`, required: true }), localError !== null && _jsx("p", { className: "text-[12px] text-danger", children: localError }), signUp.error !== null && _jsx(ErrorPanel, { error: signUp.error }), _jsx(SubmitButton, { label: "Continue", pendingLabel: "Creating\u2026", isPending: signUp.isPending })] }) }));
|
|
42
48
|
}
|
|
43
49
|
//# sourceMappingURL=SignUpPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignUpPage.js","sourceRoot":"","sources":["../../../src/pages/auth/SignUpPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAiC,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAgB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAE7C
|
|
1
|
+
{"version":3,"file":"SignUpPage.js","sourceRoot":"","sources":["../../../src/pages/auth/SignUpPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAiC,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAgB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAE7C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACpC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC5C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAEjE,SAAS,MAAM,CAAC,KAAgB;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAA;QAEtB,wEAAwE;QACxE,oDAAoD;QACpD,IAAI,QAAQ,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;YAC9C,aAAa,CAAC,6BAA6B,MAAM,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAA;YAEzF,OAAM;QACR,CAAC;QAED,aAAa,CAAC,IAAI,CAAC,CAAA;QAEnB,MAAM;aACH,QAAQ,CAAC;YACR,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YACjB,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;YACnB,QAAQ;SACT,CAAC;aACD,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;aAChE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO,CACL,KAAC,UAAU,IACT,KAAK,EAAC,gBAAgB,EACtB,WAAW,EAAC,4EAA4E,EACxF,MAAM,EACJ,gBAAM,SAAS,EAAC,gBAAgB,yCACL,GAAG,EAC5B,KAAC,IAAI,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAC,yCAAyC,wBAE9D,IACF,YAGT,gBAAM,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,gBAAgB,aAChD,KAAC,SAAS,IACR,KAAK,EAAC,WAAW,EACjB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,OAAO,EACjB,YAAY,EAAC,MAAM,EACnB,QAAQ,SACR,EACF,KAAC,SAAS,IACR,KAAK,EAAC,OAAO,EACb,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAC,OAAO,EACpB,QAAQ,SACR,EACF,KAAC,SAAS,IACR,KAAK,EAAC,UAAU,EAChB,IAAI,EAAC,UAAU,EACf,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,WAAW,EACrB,YAAY,EAAC,cAAc,EAC3B,IAAI,EAAE,YAAY,MAAM,CAAC,uBAAuB,CAAC,cAAc,EAC/D,QAAQ,SACR,EACD,UAAU,KAAK,IAAI,IAAI,YAAG,SAAS,EAAC,yBAAyB,YAAE,UAAU,GAAK,EAC9E,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,KAAC,UAAU,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAI,EAC7D,KAAC,YAAY,IAAC,KAAK,EAAC,UAAU,EAAC,YAAY,EAAC,gBAAW,EAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAI,IAClF,GACI,CACd,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a verification email lands: `/verify-email?token=…`.
|
|
3
|
+
*
|
|
4
|
+
* Spent automatically on load, unlike accepting an invitation: confirming
|
|
5
|
+
* only flips whether the account is verified. There is no workspace
|
|
6
|
+
* membership or other side effect a confirmation button would be guarding.
|
|
7
|
+
*/
|
|
8
|
+
export declare function VerifyEmailConfirmPage(): React.JSX.Element;
|
|
9
|
+
//# sourceMappingURL=VerifyEmailConfirmPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyEmailConfirmPage.d.ts","sourceRoot":"","sources":["../../../src/pages/auth/VerifyEmailConfirmPage.tsx"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAkE1D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { Navigate, useSearchParams } from 'react-router';
|
|
4
|
+
import { useConfirmEmailVerification, useSession } from '../../api/resources/session.js';
|
|
5
|
+
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.js';
|
|
6
|
+
import { AuthLayout } from './AuthLayout.js';
|
|
7
|
+
/**
|
|
8
|
+
* Where a verification email lands: `/verify-email?token=…`.
|
|
9
|
+
*
|
|
10
|
+
* Spent automatically on load, unlike accepting an invitation: confirming
|
|
11
|
+
* only flips whether the account is verified. There is no workspace
|
|
12
|
+
* membership or other side effect a confirmation button would be guarding.
|
|
13
|
+
*/
|
|
14
|
+
export function VerifyEmailConfirmPage() {
|
|
15
|
+
const [searchParameters] = useSearchParams();
|
|
16
|
+
const token = searchParameters.get('token') ?? '';
|
|
17
|
+
const confirm = useConfirmEmailVerification();
|
|
18
|
+
// `confirm` is a fresh object every render, so the effect below reads it
|
|
19
|
+
// through a ref rather than depending on it: depending on it would spend
|
|
20
|
+
// the token again on every render instead of once per token.
|
|
21
|
+
const confirmRef = useRef(confirm);
|
|
22
|
+
confirmRef.current = confirm;
|
|
23
|
+
const { isLoading, isSignedOut, needsWorkspace } = useSession();
|
|
24
|
+
const [succeeded, setSucceeded] = useState(false);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (token.length === 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Guards a state update after the token was already spent by an earlier
|
|
30
|
+
// mount of this effect, not a retry: the request itself only ever fires
|
|
31
|
+
// once per token, since `token` is the only dependency.
|
|
32
|
+
let active = true;
|
|
33
|
+
confirmRef.current
|
|
34
|
+
.runAsync({ token })
|
|
35
|
+
.then(() => {
|
|
36
|
+
if (active) {
|
|
37
|
+
setSucceeded(true);
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.catch(() => undefined);
|
|
41
|
+
return () => {
|
|
42
|
+
active = false;
|
|
43
|
+
};
|
|
44
|
+
}, [token]);
|
|
45
|
+
if (token.length === 0) {
|
|
46
|
+
return (_jsx(AuthLayout, { title: "This link is incomplete", children: _jsx("p", { className: "mt-4 text-[13px] text-ink-muted", children: "It carries no verification token." }) }));
|
|
47
|
+
}
|
|
48
|
+
if (confirm.error !== null) {
|
|
49
|
+
return (_jsx(AuthLayout, { title: "This link is invalid or has expired", children: _jsx("div", { className: "mt-4", children: _jsx(ErrorPanel, { error: confirm.error }) }) }));
|
|
50
|
+
}
|
|
51
|
+
if (!succeeded || isLoading) {
|
|
52
|
+
return _jsx(LoadingPanel, {});
|
|
53
|
+
}
|
|
54
|
+
// Confirmed. A signed-in caller moves on; `SessionGate` and the onboarding
|
|
55
|
+
// routes take it from there. A signed-out one goes to sign in.
|
|
56
|
+
return (_jsx(Navigate, { to: isSignedOut ? '/login' : needsWorkspace ? '/onboarding/workspace' : '/dashboard', replace: true }));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=VerifyEmailConfirmPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyEmailConfirmPage.js","sourceRoot":"","sources":["../../../src/pages/auth/VerifyEmailConfirmPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAExD,OAAO,EAAE,2BAA2B,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AACxF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gCAAiC,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,CAAC,gBAAgB,CAAC,GAAG,eAAe,EAAE,CAAA;IAC5C,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;IACjD,MAAM,OAAO,GAAG,2BAA2B,EAAE,CAAA;IAC7C,yEAAyE;IACzE,yEAAyE;IACzE,6DAA6D;IAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;IAClC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAA;IAC5B,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,UAAU,EAAE,CAAA;IAC/D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QAED,wEAAwE;QACxE,wEAAwE;QACxE,wDAAwD;QACxD,IAAI,MAAM,GAAG,IAAI,CAAA;QAEjB,UAAU,CAAC,OAAO;aACf,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;aACnB,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,MAAM,EAAE,CAAC;gBACX,YAAY,CAAC,IAAI,CAAC,CAAA;YACpB,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QAEzB,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,KAAK,CAAA;QAChB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CACL,KAAC,UAAU,IAAC,KAAK,EAAC,yBAAyB,YACzC,YAAG,SAAS,EAAC,iCAAiC,kDAAsC,GACzE,CACd,CAAA;IACH,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,CACL,KAAC,UAAU,IAAC,KAAK,EAAC,qCAAqC,YACrD,cAAK,SAAS,EAAC,MAAM,YACnB,KAAC,UAAU,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,GAAI,GAChC,GACK,CACd,CAAA;IACH,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,SAAS,EAAE,CAAC;QAC5B,OAAO,KAAC,YAAY,KAAG,CAAA;IACzB,CAAC;IAED,2EAA2E;IAC3E,+DAA+D;IAC/D,OAAO,CACL,KAAC,QAAQ,IACP,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,YAAY,EACpF,OAAO,SACP,CACH,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where `SessionGate` sends a signed-in account with no workspace and an
|
|
3
|
+
* unverified email, and where `SignUpPage` navigates straight after signup.
|
|
4
|
+
*
|
|
5
|
+
* There is nothing to submit here: the account already exists, and the first
|
|
6
|
+
* verification link already went out with `POST /v1/auth/signup`. The only
|
|
7
|
+
* actions from this screen are asking for a fresh link and signing out.
|
|
8
|
+
*/
|
|
9
|
+
export declare function VerifyEmailPendingPage(): React.JSX.Element;
|
|
10
|
+
//# sourceMappingURL=VerifyEmailPendingPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyEmailPendingPage.d.ts","sourceRoot":"","sources":["../../../src/pages/auth/VerifyEmailPendingPage.tsx"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAiD1D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Navigate } from 'react-router';
|
|
4
|
+
import { useLogOut, useRequestEmailVerification, useSession } from '../../api/resources/session.js';
|
|
5
|
+
import { ErrorPanel } from '../../components/QueryState.js';
|
|
6
|
+
import { AuthLayout } from './AuthLayout.js';
|
|
7
|
+
/**
|
|
8
|
+
* Where `SessionGate` sends a signed-in account with no workspace and an
|
|
9
|
+
* unverified email, and where `SignUpPage` navigates straight after signup.
|
|
10
|
+
*
|
|
11
|
+
* There is nothing to submit here: the account already exists, and the first
|
|
12
|
+
* verification link already went out with `POST /v1/auth/signup`. The only
|
|
13
|
+
* actions from this screen are asking for a fresh link and signing out.
|
|
14
|
+
*/
|
|
15
|
+
export function VerifyEmailPendingPage() {
|
|
16
|
+
const { isSignedOut } = useSession();
|
|
17
|
+
const requestVerification = useRequestEmailVerification();
|
|
18
|
+
const logOut = useLogOut();
|
|
19
|
+
const [resent, setResent] = useState(false);
|
|
20
|
+
if (isSignedOut) {
|
|
21
|
+
return _jsx(Navigate, { to: "/login", replace: true });
|
|
22
|
+
}
|
|
23
|
+
function resend() {
|
|
24
|
+
requestVerification
|
|
25
|
+
.runAsync()
|
|
26
|
+
.then(() => {
|
|
27
|
+
setResent(true);
|
|
28
|
+
})
|
|
29
|
+
.catch(() => undefined);
|
|
30
|
+
}
|
|
31
|
+
return (_jsx(AuthLayout, { title: "Check your email", description: "Click the link we sent to finish setting up your account.", footer: _jsx("button", { type: "button", onClick: () => {
|
|
32
|
+
logOut.runAsync().catch(() => undefined);
|
|
33
|
+
}, className: "font-medium text-accent hover:underline", children: "Sign out" }), children: _jsxs("div", { className: "mt-5 space-y-3", children: [resent && _jsx("p", { className: "text-[12px] text-ink-muted", children: "A new link is on its way." }), requestVerification.error !== null && _jsx(ErrorPanel, { error: requestVerification.error }), _jsx("button", { type: "button", disabled: requestVerification.isPending, onClick: resend, className: "w-full rounded-md bg-accent px-3.5 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover disabled:opacity-50", children: requestVerification.isPending ? 'Sending…' : 'Resend link' })] }) }));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=VerifyEmailPendingPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyEmailPendingPage.js","sourceRoot":"","sources":["../../../src/pages/auth/VerifyEmailPendingPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAiC,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAE7C;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,CAAA;IACpC,MAAM,mBAAmB,GAAG,2BAA2B,EAAE,CAAA;IACzD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE3C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,KAAC,QAAQ,IAAC,EAAE,EAAC,QAAQ,EAAC,OAAO,SAAG,CAAA;IACzC,CAAC;IAED,SAAS,MAAM;QACb,mBAAmB;aAChB,QAAQ,EAAE;aACV,IAAI,CAAC,GAAG,EAAE;YACT,SAAS,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO,CACL,KAAC,UAAU,IACT,KAAK,EAAC,kBAAkB,EACxB,WAAW,EAAC,2DAA2D,EACvE,MAAM,EACJ,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YAC1C,CAAC,EACD,SAAS,EAAC,yCAAyC,yBAG5C,YAGX,eAAK,SAAS,EAAC,gBAAgB,aAC5B,MAAM,IAAI,YAAG,SAAS,EAAC,4BAA4B,0CAA8B,EACjF,mBAAmB,CAAC,KAAK,KAAK,IAAI,IAAI,KAAC,UAAU,IAAC,KAAK,EAAE,mBAAmB,CAAC,KAAK,GAAI,EACvF,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,mBAAmB,CAAC,SAAS,EACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAC,uIAAuI,YAEhJ,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,GACpD,IACL,GACK,CACd,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kelpie/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "React UI for Kelpie: components, pages, API client, and the extension registry an assembly composes modules through.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kelpie",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@dnd-kit/core": "^6.3.1",
|
|
49
49
|
"@dnd-kit/sortable": "^10.0.0",
|
|
50
50
|
"@dnd-kit/utilities": "^3.2.2",
|
|
51
|
-
"@kelpie/schemas": "^0.
|
|
51
|
+
"@kelpie/schemas": "^0.5.1",
|
|
52
52
|
"@tanstack/react-query": "^5.101.4",
|
|
53
53
|
"react-markdown": "^10.1.0",
|
|
54
54
|
"react-router": "^8.3.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createInviteBody, inviteSchema
|
|
1
|
+
import { createInviteBody, inviteSchema } from '@kelpie/schemas'
|
|
2
2
|
import type { InvitableRole, Invite } from '@kelpie/schemas'
|
|
3
3
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
|
4
4
|
|
|
@@ -15,18 +15,12 @@ import { useSession } from './session.ts'
|
|
|
15
15
|
* only renders this half for an admin, which keeps the refusal off screen
|
|
16
16
|
* without the browser being what decides it.
|
|
17
17
|
*
|
|
18
|
-
* The URL the emailed link points at is built
|
|
19
|
-
*
|
|
20
|
-
* the placeholder it fills in.
|
|
18
|
+
* The URL the emailed link points at is built server-side from the deployment's
|
|
19
|
+
* own base URL, so nothing here sends one.
|
|
21
20
|
*/
|
|
22
21
|
|
|
23
22
|
const INVITES_KEY = 'invites'
|
|
24
23
|
|
|
25
|
-
/** Where an invitee lands. `JoinPage` reads the token out of the query string. */
|
|
26
|
-
export function inviteUrlTemplate(origin: string): string {
|
|
27
|
-
return `${origin}/join?token={token}`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
24
|
export interface InviteListResult {
|
|
31
25
|
readonly invites: readonly Invite[]
|
|
32
26
|
readonly isLoading: boolean
|
|
@@ -64,7 +58,7 @@ export function useSendInvite(): MutationResult<SendInviteArguments, Invite> {
|
|
|
64
58
|
mutationFn: ({ email, role }: SendInviteArguments) =>
|
|
65
59
|
client.post(
|
|
66
60
|
`/workspaces/${workspaceId}/invites`,
|
|
67
|
-
createInviteBody({ email, role
|
|
61
|
+
createInviteBody({ email, role }),
|
|
68
62
|
inviteSchema.parse,
|
|
69
63
|
),
|
|
70
64
|
onSuccess: async () => {
|
|
@@ -83,11 +77,7 @@ export function useResendInvite(): MutationResult<string, Invite> {
|
|
|
83
77
|
const workspaceId = session?.workspaceId ?? ''
|
|
84
78
|
const mutation = useMutation({
|
|
85
79
|
mutationFn: (inviteId: string) =>
|
|
86
|
-
client.post(
|
|
87
|
-
`/workspaces/${workspaceId}/invites/${inviteId}/resend`,
|
|
88
|
-
resendInviteBody({ inviteUrlTemplate: inviteUrlTemplate(window.location.origin) }),
|
|
89
|
-
inviteSchema.parse,
|
|
90
|
-
),
|
|
80
|
+
client.post(`/workspaces/${workspaceId}/invites/${inviteId}/resend`, {}, inviteSchema.parse),
|
|
91
81
|
onSuccess: async () => {
|
|
92
82
|
await queryClient.invalidateQueries({ queryKey: [INVITES_KEY, workspaceId] })
|
|
93
83
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
confirmEmailVerificationBody,
|
|
2
3
|
confirmPasswordResetBody,
|
|
3
4
|
createWorkspaceBody,
|
|
4
5
|
logInBody,
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
workspaceSchema,
|
|
10
11
|
} from '@kelpie/schemas'
|
|
11
12
|
import type {
|
|
13
|
+
ConfirmEmailVerificationInput,
|
|
12
14
|
ConfirmPasswordResetInput,
|
|
13
15
|
CreateWorkspaceInput,
|
|
14
16
|
LogInInput,
|
|
@@ -63,6 +65,8 @@ export interface SessionState {
|
|
|
63
65
|
readonly isSignedOut: boolean
|
|
64
66
|
/** Signed in, but the account has no workspace yet. Every CRM endpoint answers `403` until it does. */
|
|
65
67
|
readonly needsWorkspace: boolean
|
|
68
|
+
/** No workspace yet, and creating one will answer `403` until the account verifies its email. */
|
|
69
|
+
readonly needsEmailVerification: boolean
|
|
66
70
|
readonly error: Error | null
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -70,12 +74,14 @@ export function useSession(): SessionState {
|
|
|
70
74
|
const client = useApiClient()
|
|
71
75
|
const result = useQuery(sessionQuery(client))
|
|
72
76
|
const isSignedOut = result.error instanceof ApiError && result.error.status === 401
|
|
77
|
+
const needsWorkspace = result.data !== undefined && result.data.workspaceId === null
|
|
73
78
|
|
|
74
79
|
return {
|
|
75
80
|
session: result.data,
|
|
76
81
|
isLoading: result.isPending,
|
|
77
82
|
isSignedOut,
|
|
78
|
-
needsWorkspace
|
|
83
|
+
needsWorkspace,
|
|
84
|
+
needsEmailVerification: needsWorkspace && result.data?.emailVerified === false,
|
|
79
85
|
error: isSignedOut ? null : toError(result.error),
|
|
80
86
|
}
|
|
81
87
|
}
|
|
@@ -132,11 +138,6 @@ export function useLogOut(): MutationResult<void, void> {
|
|
|
132
138
|
return asMutationResult(mutation)
|
|
133
139
|
}
|
|
134
140
|
|
|
135
|
-
/** Where a reset email lands. `ResetPasswordPage` reads the token out of the query string. */
|
|
136
|
-
export function resetUrlTemplate(origin: string): string {
|
|
137
|
-
return `${origin}/reset-password?token={token}`
|
|
138
|
-
}
|
|
139
|
-
|
|
140
141
|
/**
|
|
141
142
|
* Asks for a reset link.
|
|
142
143
|
*
|
|
@@ -176,6 +177,41 @@ export function useConfirmPasswordReset(): MutationResult<ConfirmPasswordResetIn
|
|
|
176
177
|
return asMutationResult(mutation)
|
|
177
178
|
}
|
|
178
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Asks for a fresh verification link. The same call a "resend" button makes,
|
|
182
|
+
* and a no-op once the account is already verified.
|
|
183
|
+
*
|
|
184
|
+
* Nothing in the cache changes: this signs nobody in or out.
|
|
185
|
+
*/
|
|
186
|
+
export function useRequestEmailVerification(): MutationResult<void, void> {
|
|
187
|
+
const client = useApiClient()
|
|
188
|
+
const mutation = useMutation({
|
|
189
|
+
mutationFn: () => client.postEmpty('/auth/verify-email'),
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
return asMutationResult(mutation)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Spends a verification token from that email.
|
|
197
|
+
*
|
|
198
|
+
* Unlike a password reset this ends no session, so the caller only needs the
|
|
199
|
+
* session re-read: `needsEmailVerification` flips once it lands.
|
|
200
|
+
*/
|
|
201
|
+
export function useConfirmEmailVerification(): MutationResult<ConfirmEmailVerificationInput, void> {
|
|
202
|
+
const client = useApiClient()
|
|
203
|
+
const queryClient = useQueryClient()
|
|
204
|
+
const mutation = useMutation({
|
|
205
|
+
mutationFn: (input: ConfirmEmailVerificationInput) =>
|
|
206
|
+
client.postEmpty('/auth/verify-email/confirm', confirmEmailVerificationBody(input)),
|
|
207
|
+
onSuccess: async () => {
|
|
208
|
+
await queryClient.fetchQuery(sessionQuery(client))
|
|
209
|
+
},
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
return asMutationResult(mutation)
|
|
213
|
+
}
|
|
214
|
+
|
|
179
215
|
/**
|
|
180
216
|
* Joins the workspace an invitation names.
|
|
181
217
|
*
|
package/src/app/KelpieApp.tsx
CHANGED
|
@@ -43,6 +43,8 @@ import { JoinPage } from '../pages/auth/JoinPage.tsx'
|
|
|
43
43
|
import { ResetPasswordPage } from '../pages/auth/ResetPasswordPage.tsx'
|
|
44
44
|
import { SignInPage } from '../pages/auth/SignInPage.tsx'
|
|
45
45
|
import { SignUpPage } from '../pages/auth/SignUpPage.tsx'
|
|
46
|
+
import { VerifyEmailConfirmPage } from '../pages/auth/VerifyEmailConfirmPage.tsx'
|
|
47
|
+
import { VerifyEmailPendingPage } from '../pages/auth/VerifyEmailPendingPage.tsx'
|
|
46
48
|
import { DashboardPage } from '../pages/dashboard/DashboardPage.tsx'
|
|
47
49
|
import { HandbookLayout } from '../pages/handbook/HandbookPage.tsx'
|
|
48
50
|
import { HandbookStepPage } from '../pages/onboarding/HandbookStepPage.tsx'
|
|
@@ -112,10 +114,13 @@ function AppRoutes(): React.JSX.Element {
|
|
|
112
114
|
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
|
|
113
115
|
<Route path="/reset-password" element={<ResetPasswordPage />} />
|
|
114
116
|
{/* Outside the gate: an invitee may have no workspace yet, and this is how
|
|
115
|
-
they get one. Same for the first onboarding step,
|
|
116
|
-
|
|
117
|
+
they get one. Same for the first onboarding step, and for the two
|
|
118
|
+
verification pages, all of which are what the gate sends an account
|
|
119
|
+
with no workspace to. */}
|
|
117
120
|
<Route path="/join" element={<JoinPage />} />
|
|
118
121
|
<Route path="/onboarding/workspace" element={<WorkspaceStepPage />} />
|
|
122
|
+
<Route path="/verify-email" element={<VerifyEmailConfirmPage />} />
|
|
123
|
+
<Route path="/verify-email/pending" element={<VerifyEmailPendingPage />} />
|
|
119
124
|
|
|
120
125
|
<Route element={<SessionGate />}>
|
|
121
126
|
{/* Inside the gate and outside the Shell: both steps need the workspace
|
package/src/app/SessionGate.tsx
CHANGED
|
@@ -6,17 +6,21 @@ import { ErrorPanel, LoadingPanel } from '../components/QueryState.tsx'
|
|
|
6
6
|
/**
|
|
7
7
|
* What stands between a URL and a page that needs a workspace.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Four answers, and they are not the same thing:
|
|
10
10
|
*
|
|
11
11
|
* - `401` means sign in. That is a redirect.
|
|
12
|
-
* - Signed in
|
|
12
|
+
* - Signed in, no workspace, email unverified means go verify it: creating a
|
|
13
|
+
* workspace answers `403` until then. Checked before `needsWorkspace`,
|
|
14
|
+
* since both are true at once for a fresh direct signup and this is the one
|
|
15
|
+
* that has to happen first.
|
|
16
|
+
* - Signed in, no workspace, verified means create one. Also a redirect, to a
|
|
13
17
|
* different place, because sending someone to a sign-in form they have
|
|
14
18
|
* already passed is a loop.
|
|
15
19
|
* - Anything else is the service being unreachable or broken, and redirecting
|
|
16
20
|
* on that would hide it behind a sign-in form that will also fail.
|
|
17
21
|
*/
|
|
18
22
|
export function SessionGate(): React.JSX.Element {
|
|
19
|
-
const { isLoading, isSignedOut, needsWorkspace, error } = useSession()
|
|
23
|
+
const { isLoading, isSignedOut, needsWorkspace, needsEmailVerification, error } = useSession()
|
|
20
24
|
|
|
21
25
|
if (isSignedOut) {
|
|
22
26
|
return <Navigate to="/login" replace />
|
|
@@ -34,6 +38,10 @@ export function SessionGate(): React.JSX.Element {
|
|
|
34
38
|
return <LoadingPanel />
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
if (needsEmailVerification) {
|
|
42
|
+
return <Navigate to="/verify-email/pending" replace />
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
if (needsWorkspace) {
|
|
38
46
|
return <Navigate to="/onboarding/workspace" replace />
|
|
39
47
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { useState } from 'react'
|
|
|
2
2
|
import type { FormEvent } from 'react'
|
|
3
3
|
import { Link } from 'react-router'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useRequestPasswordReset } from '../../api/resources/session.ts'
|
|
6
6
|
import { ErrorPanel } from '../../components/QueryState.tsx'
|
|
7
7
|
import { SubmitButton, TextField } from './AuthForm.tsx'
|
|
8
8
|
import { AuthLayout } from './AuthLayout.tsx'
|
|
@@ -29,7 +29,7 @@ export function ForgotPasswordPage(): React.JSX.Element {
|
|
|
29
29
|
const address = email.trim()
|
|
30
30
|
|
|
31
31
|
request
|
|
32
|
-
.runAsync({ email: address
|
|
32
|
+
.runAsync({ email: address })
|
|
33
33
|
.then(() => {
|
|
34
34
|
setSentTo(address)
|
|
35
35
|
})
|
|
@@ -11,9 +11,11 @@ import { AuthLayout } from './AuthLayout.tsx'
|
|
|
11
11
|
/**
|
|
12
12
|
* Creating an account, against `POST /v1/auth/signup`.
|
|
13
13
|
*
|
|
14
|
-
* Signup makes the user and nothing else, per `onboarding.md`, so success
|
|
15
|
-
* on the
|
|
16
|
-
*
|
|
14
|
+
* Signup makes the user and nothing else, per `onboarding.md`, so success
|
|
15
|
+
* lands on the email-verification screen rather than in the app or the first
|
|
16
|
+
* onboarding step: the account cannot create a workspace until it verifies.
|
|
17
|
+
* The response sets the session cookie, which is why that next page can
|
|
18
|
+
* already act as the signed-in account.
|
|
17
19
|
*
|
|
18
20
|
* The mockup collected this into `sessionStorage` and committed the lot at the
|
|
19
21
|
* end of the wizard. Here each step commits as it is finished: a draft account
|
|
@@ -41,15 +43,19 @@ export function SignUpPage(): React.JSX.Element {
|
|
|
41
43
|
setLocalError(null)
|
|
42
44
|
|
|
43
45
|
signUp
|
|
44
|
-
.runAsync({
|
|
45
|
-
|
|
46
|
+
.runAsync({
|
|
47
|
+
name: name.trim(),
|
|
48
|
+
email: email.trim(),
|
|
49
|
+
password,
|
|
50
|
+
})
|
|
51
|
+
.then(() => navigate('/verify-email/pending', { replace: true }))
|
|
46
52
|
.catch(() => undefined)
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
return (
|
|
50
56
|
<AuthLayout
|
|
51
57
|
title="Create account"
|
|
52
|
-
description="Next you will create a workspace for your company."
|
|
58
|
+
description="Next you will verify your email, then create a workspace for your company."
|
|
53
59
|
footer={
|
|
54
60
|
<span className="text-ink-muted">
|
|
55
61
|
Already have an account?{' '}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react'
|
|
2
|
+
import { Navigate, useSearchParams } from 'react-router'
|
|
3
|
+
|
|
4
|
+
import { useConfirmEmailVerification, useSession } from '../../api/resources/session.ts'
|
|
5
|
+
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
|
|
6
|
+
import { AuthLayout } from './AuthLayout.tsx'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Where a verification email lands: `/verify-email?token=…`.
|
|
10
|
+
*
|
|
11
|
+
* Spent automatically on load, unlike accepting an invitation: confirming
|
|
12
|
+
* only flips whether the account is verified. There is no workspace
|
|
13
|
+
* membership or other side effect a confirmation button would be guarding.
|
|
14
|
+
*/
|
|
15
|
+
export function VerifyEmailConfirmPage(): React.JSX.Element {
|
|
16
|
+
const [searchParameters] = useSearchParams()
|
|
17
|
+
const token = searchParameters.get('token') ?? ''
|
|
18
|
+
const confirm = useConfirmEmailVerification()
|
|
19
|
+
// `confirm` is a fresh object every render, so the effect below reads it
|
|
20
|
+
// through a ref rather than depending on it: depending on it would spend
|
|
21
|
+
// the token again on every render instead of once per token.
|
|
22
|
+
const confirmRef = useRef(confirm)
|
|
23
|
+
confirmRef.current = confirm
|
|
24
|
+
const { isLoading, isSignedOut, needsWorkspace } = useSession()
|
|
25
|
+
const [succeeded, setSucceeded] = useState(false)
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (token.length === 0) {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Guards a state update after the token was already spent by an earlier
|
|
33
|
+
// mount of this effect, not a retry: the request itself only ever fires
|
|
34
|
+
// once per token, since `token` is the only dependency.
|
|
35
|
+
let active = true
|
|
36
|
+
|
|
37
|
+
confirmRef.current
|
|
38
|
+
.runAsync({ token })
|
|
39
|
+
.then(() => {
|
|
40
|
+
if (active) {
|
|
41
|
+
setSucceeded(true)
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
.catch(() => undefined)
|
|
45
|
+
|
|
46
|
+
return () => {
|
|
47
|
+
active = false
|
|
48
|
+
}
|
|
49
|
+
}, [token])
|
|
50
|
+
|
|
51
|
+
if (token.length === 0) {
|
|
52
|
+
return (
|
|
53
|
+
<AuthLayout title="This link is incomplete">
|
|
54
|
+
<p className="mt-4 text-[13px] text-ink-muted">It carries no verification token.</p>
|
|
55
|
+
</AuthLayout>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (confirm.error !== null) {
|
|
60
|
+
return (
|
|
61
|
+
<AuthLayout title="This link is invalid or has expired">
|
|
62
|
+
<div className="mt-4">
|
|
63
|
+
<ErrorPanel error={confirm.error} />
|
|
64
|
+
</div>
|
|
65
|
+
</AuthLayout>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!succeeded || isLoading) {
|
|
70
|
+
return <LoadingPanel />
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Confirmed. A signed-in caller moves on; `SessionGate` and the onboarding
|
|
74
|
+
// routes take it from there. A signed-out one goes to sign in.
|
|
75
|
+
return (
|
|
76
|
+
<Navigate
|
|
77
|
+
to={isSignedOut ? '/login' : needsWorkspace ? '/onboarding/workspace' : '/dashboard'}
|
|
78
|
+
replace
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { Navigate } from 'react-router'
|
|
3
|
+
|
|
4
|
+
import { useLogOut, useRequestEmailVerification, useSession } from '../../api/resources/session.ts'
|
|
5
|
+
import { ErrorPanel } from '../../components/QueryState.tsx'
|
|
6
|
+
import { AuthLayout } from './AuthLayout.tsx'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Where `SessionGate` sends a signed-in account with no workspace and an
|
|
10
|
+
* unverified email, and where `SignUpPage` navigates straight after signup.
|
|
11
|
+
*
|
|
12
|
+
* There is nothing to submit here: the account already exists, and the first
|
|
13
|
+
* verification link already went out with `POST /v1/auth/signup`. The only
|
|
14
|
+
* actions from this screen are asking for a fresh link and signing out.
|
|
15
|
+
*/
|
|
16
|
+
export function VerifyEmailPendingPage(): React.JSX.Element {
|
|
17
|
+
const { isSignedOut } = useSession()
|
|
18
|
+
const requestVerification = useRequestEmailVerification()
|
|
19
|
+
const logOut = useLogOut()
|
|
20
|
+
const [resent, setResent] = useState(false)
|
|
21
|
+
|
|
22
|
+
if (isSignedOut) {
|
|
23
|
+
return <Navigate to="/login" replace />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resend(): void {
|
|
27
|
+
requestVerification
|
|
28
|
+
.runAsync()
|
|
29
|
+
.then(() => {
|
|
30
|
+
setResent(true)
|
|
31
|
+
})
|
|
32
|
+
.catch(() => undefined)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<AuthLayout
|
|
37
|
+
title="Check your email"
|
|
38
|
+
description="Click the link we sent to finish setting up your account."
|
|
39
|
+
footer={
|
|
40
|
+
<button
|
|
41
|
+
type="button"
|
|
42
|
+
onClick={() => {
|
|
43
|
+
logOut.runAsync().catch(() => undefined)
|
|
44
|
+
}}
|
|
45
|
+
className="font-medium text-accent hover:underline"
|
|
46
|
+
>
|
|
47
|
+
Sign out
|
|
48
|
+
</button>
|
|
49
|
+
}
|
|
50
|
+
>
|
|
51
|
+
<div className="mt-5 space-y-3">
|
|
52
|
+
{resent && <p className="text-[12px] text-ink-muted">A new link is on its way.</p>}
|
|
53
|
+
{requestVerification.error !== null && <ErrorPanel error={requestVerification.error} />}
|
|
54
|
+
<button
|
|
55
|
+
type="button"
|
|
56
|
+
disabled={requestVerification.isPending}
|
|
57
|
+
onClick={resend}
|
|
58
|
+
className="w-full rounded-md bg-accent px-3.5 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover disabled:opacity-50"
|
|
59
|
+
>
|
|
60
|
+
{requestVerification.isPending ? 'Sending…' : 'Resend link'}
|
|
61
|
+
</button>
|
|
62
|
+
</div>
|
|
63
|
+
</AuthLayout>
|
|
64
|
+
)
|
|
65
|
+
}
|