fix: add public profiles tests
This commit is contained in:
@@ -60,7 +60,7 @@ export default function PublicProfilePage({ loaderData }: Route.ComponentProps)
|
|||||||
const { _ } = useLingui();
|
const { _ } = useLingui();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
const { user } = useSession();
|
const { user, refreshSession } = useSession();
|
||||||
const team = useOptionalCurrentTeam();
|
const team = useOptionalCurrentTeam();
|
||||||
|
|
||||||
const [isPublicProfileVisible, setIsPublicProfileVisible] = useState(profile.enabled);
|
const [isPublicProfileVisible, setIsPublicProfileVisible] = useState(profile.enabled);
|
||||||
@@ -96,6 +96,9 @@ export default function PublicProfilePage({ loaderData }: Route.ComponentProps)
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await updateUserProfile(data);
|
await updateUserProfile(data);
|
||||||
|
|
||||||
|
// Need to refresh session because we're editing the user's profile.
|
||||||
|
await refreshSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.enabled === undefined && !isPublicProfileVisible) {
|
if (data.enabled === undefined && !isPublicProfileVisible) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { ChevronLeft } from 'lucide-react';
|
|||||||
import { Link, Outlet } from 'react-router';
|
import { Link, Outlet } from 'react-router';
|
||||||
|
|
||||||
import LogoIcon from '@documenso/assets/logo_icon.png';
|
import LogoIcon from '@documenso/assets/logo_icon.png';
|
||||||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
import { useOptionalSession } from '@documenso/lib/client-only/providers/session';
|
||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ export function meta() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function PublicProfileLayout() {
|
export default function PublicProfileLayout() {
|
||||||
const session = useSession();
|
const { sessionData } = useOptionalSession();
|
||||||
|
|
||||||
const [scrollY, setScrollY] = useState(0);
|
const [scrollY, setScrollY] = useState(0);
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ export default function PublicProfileLayout() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen">
|
<div className="min-h-screen">
|
||||||
{session ? (
|
{sessionData ? (
|
||||||
<AuthenticatedHeader user={session.user} teams={session.teams} />
|
<AuthenticatedHeader user={sessionData.user} teams={sessionData.teams} />
|
||||||
) : (
|
) : (
|
||||||
<header
|
<header
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||||||
profileUrl,
|
profileUrl,
|
||||||
}).catch(() => null);
|
}).catch(() => null);
|
||||||
|
|
||||||
// Todo: Test
|
|
||||||
if (!publicProfile || !publicProfile.profile.enabled) {
|
if (!publicProfile || !publicProfile.profile.enabled) {
|
||||||
throw new Response('Not Found', { status: 404 });
|
throw new Response('Not Found', { status: 404 });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default function RecipientLayout() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Use generic error boundary.
|
// Todo: (RR7) Use generic error boundary.
|
||||||
export function ErrorBoundary() {
|
export function ErrorBoundary() {
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto flex min-h-[80vh] w-full items-center justify-center py-32">
|
<div className="mx-auto flex min-h-[80vh] w-full items-center justify-center py-32">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Todo: Test, used AI to migrate this component from NextJS to Remix.
|
// Todo: (RR7) Test, used AI to migrate this component from NextJS to Remix.
|
||||||
import satori from 'satori';
|
import satori from 'satori';
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
import { P, match } from 'ts-pattern';
|
import { P, match } from 'ts-pattern';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL } from '@documenso/li
|
|||||||
|
|
||||||
import type { Route } from './+types/share.$slug';
|
import type { Route } from './+types/share.$slug';
|
||||||
|
|
||||||
// Todo: Test meta.
|
// Todo: (RR7) Test meta.
|
||||||
export function meta({ params: { slug } }: Route.MetaArgs) {
|
export function meta({ params: { slug } }: Route.MetaArgs) {
|
||||||
return [
|
return [
|
||||||
{ title: 'Documenso - Share' },
|
{ title: 'Documenso - Share' },
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export type ShareHandlerAPIResponse =
|
|||||||
| Awaited<ReturnType<typeof getRecipientOrSenderByShareLinkSlug>>
|
| Awaited<ReturnType<typeof getRecipientOrSenderByShareLinkSlug>>
|
||||||
| { error: string };
|
| { error: string };
|
||||||
|
|
||||||
// Todo: Test
|
// Todo: (RR7) Test
|
||||||
export async function loader({ request }: Route.LoaderArgs) {
|
export async function loader({ request }: Route.LoaderArgs) {
|
||||||
try {
|
try {
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { stripeWebhookHandler } from '@documenso/ee/server-only/stripe/webhook/handler';
|
import { stripeWebhookHandler } from '@documenso/ee/server-only/stripe/webhook/handler';
|
||||||
|
|
||||||
// Todo
|
// Todo: (RR7)
|
||||||
// export const config = {
|
// export const config = {
|
||||||
// api: { bodyParser: false },
|
// api: { bodyParser: false },
|
||||||
// };
|
// };
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { handlerTriggerWebhooks } from '@documenso/lib/server-only/webhooks/trig
|
|||||||
|
|
||||||
import type { Route } from './+types/webhook.trigger';
|
import type { Route } from './+types/webhook.trigger';
|
||||||
|
|
||||||
// Todo
|
// Todo: (RR7)
|
||||||
// export const config = {
|
// export const config = {
|
||||||
// maxDuration: 300,
|
// maxDuration: 300,
|
||||||
// api: {
|
// api: {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { EmbedPaywall } from '~/components/embed/embed-paywall';
|
|||||||
|
|
||||||
import type { Route } from './+types/_layout';
|
import type { Route } from './+types/_layout';
|
||||||
|
|
||||||
// Todo: Test
|
// Todo: (RR7) Test
|
||||||
export function headers({ loaderHeaders }: Route.HeadersArgs) {
|
export function headers({ loaderHeaders }: Route.HeadersArgs) {
|
||||||
const origin = loaderHeaders.get('Origin') ?? '*';
|
const origin = loaderHeaders.get('Origin') ?? '*';
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const filesRoute = new Hono<HonoEnv>()
|
|||||||
return c.json({ error: 'No file provided' }, 400);
|
return c.json({ error: 'No file provided' }, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: This is new.
|
// Todo: (RR7) This is new.
|
||||||
// Add file size validation.
|
// Add file size validation.
|
||||||
// Convert MB to bytes (1 MB = 1024 * 1024 bytes)
|
// Convert MB to bytes (1 MB = 1024 * 1024 bytes)
|
||||||
const MAX_FILE_SIZE = APP_DOCUMENT_UPLOAD_SIZE_LIMIT * 1024 * 1024;
|
const MAX_FILE_SIZE = APP_DOCUMENT_UPLOAD_SIZE_LIMIT * 1024 * 1024;
|
||||||
@@ -54,7 +54,7 @@ export const filesRoute = new Hono<HonoEnv>()
|
|||||||
throw new AppError('INVALID_DOCUMENT_FILE');
|
throw new AppError('INVALID_DOCUMENT_FILE');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Test this.
|
// Todo: (RR7) Test this.
|
||||||
if (!file.name.endsWith('.pdf')) {
|
if (!file.name.endsWith('.pdf')) {
|
||||||
Object.defineProperty(file, 'name', {
|
Object.defineProperty(file, 'name', {
|
||||||
writable: true,
|
writable: true,
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ app.route('/api/auth', auth);
|
|||||||
// Files route.
|
// Files route.
|
||||||
app.route('/api/files', filesRoute);
|
app.route('/api/files', filesRoute);
|
||||||
|
|
||||||
// API servers. Todo: Configure max durations, etc?
|
// API servers. Todo: (RR7) Configure max durations, etc?
|
||||||
app.route('/api/v1', tsRestHonoApp);
|
app.route('/api/v1', tsRestHonoApp);
|
||||||
app.use('/api/jobs/*', jobsClient.getApiHandler());
|
app.use('/api/jobs/*', jobsClient.getApiHandler());
|
||||||
app.use('/api/trpc/*', reactRouterTrpcServer);
|
app.use('/api/trpc/*', reactRouterTrpcServer);
|
||||||
|
|
||||||
// Unstable API server routes. Order matters for these two.
|
// Unstable API server routes. Order matters for these two.
|
||||||
app.get(`${API_V2_BETA_URL}/openapi.json`, (c) => c.json(openApiDocument));
|
app.get(`${API_V2_BETA_URL}/openapi.json`, (c) => c.json(openApiDocument));
|
||||||
app.use(`${API_V2_BETA_URL}/*`, async (c) => openApiTrpcServerHandler(c)); // Todo: Add next()?
|
app.use(`${API_V2_BETA_URL}/*`, async (c) => openApiTrpcServerHandler(c)); // Todo: (RR7) Add next()?
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ export const openApiTrpcServerHandler = async (c: Context) => {
|
|||||||
return createOpenApiFetchHandler<typeof appRouter>({
|
return createOpenApiFetchHandler<typeof appRouter>({
|
||||||
endpoint: API_V2_BETA_URL,
|
endpoint: API_V2_BETA_URL,
|
||||||
router: appRouter,
|
router: appRouter,
|
||||||
// Todo: Test this, since it's not using the createContext params.
|
// Todo: (RR7) Test this, since it's not using the createContext params.
|
||||||
// Todo: Reduce calls since we fetch on most request? maybe
|
// Todo: (RR7) Reduce calls since we fetch on most request? maybe
|
||||||
createContext: async () => createTrpcContext({ c, requestSource: 'apiV2' }),
|
createContext: async () => createTrpcContext({ c, requestSource: 'apiV2' }),
|
||||||
req: c.req.raw,
|
req: c.req.raw,
|
||||||
onError: (opts) => handleTrpcRouterError(opts, 'apiV2'),
|
onError: (opts) => handleTrpcRouterError(opts, 'apiV2'),
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ tsRestHonoApp
|
|||||||
.get('/openapi.json', (c) => c.json(OpenAPIV1))
|
.get('/openapi.json', (c) => c.json(OpenAPIV1))
|
||||||
.get('/me', async (c) => testCredentialsHandler(c.req.raw));
|
.get('/me', async (c) => testCredentialsHandler(c.req.raw));
|
||||||
|
|
||||||
// Zapier. Todo: Check methods. Are these get/post/update requests?
|
// Zapier. Todo: (RR7) Check methods. Are these get/post/update requests?
|
||||||
// Todo: Is there really no validations?
|
// Todo: (RR7) Is there really no validations?
|
||||||
tsRestHonoApp
|
tsRestHonoApp
|
||||||
.all('/zapier/list-documents', async (c) => listDocumentsHandler(c.req.raw))
|
.all('/zapier/list-documents', async (c) => listDocumentsHandler(c.req.raw))
|
||||||
.all('/zapier/subscribe', async (c) => subscribeHandler(c.req.raw))
|
.all('/zapier/subscribe', async (c) => subscribeHandler(c.req.raw))
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const authenticatedMiddleware = <
|
|||||||
}
|
}
|
||||||
|
|
||||||
const metadata: ApiRequestMetadata = {
|
const metadata: ApiRequestMetadata = {
|
||||||
requestMetadata: extractRequestMetadata(request), // Todo: Test
|
requestMetadata: extractRequestMetadata(request), // Todo: (RR7) Test
|
||||||
source: 'apiV1',
|
source: 'apiV1',
|
||||||
auth: 'api',
|
auth: 'api',
|
||||||
auditUser: {
|
auditUser: {
|
||||||
|
|||||||
144
packages/app-tests/e2e/public-profiles/public-profiles.spec.ts
Normal file
144
packages/app-tests/e2e/public-profiles/public-profiles.spec.ts
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||||
|
import { seedTeam } from '@documenso/prisma/seed/teams';
|
||||||
|
import { seedDirectTemplate } from '@documenso/prisma/seed/templates';
|
||||||
|
import { seedUser } from '@documenso/prisma/seed/users';
|
||||||
|
|
||||||
|
import { apiSignin } from '../fixtures/authentication';
|
||||||
|
|
||||||
|
test.describe.configure({ mode: 'parallel' });
|
||||||
|
|
||||||
|
test('[PUBLIC_PROFILE]: create profile', async ({ page }) => {
|
||||||
|
const user = await seedUser();
|
||||||
|
|
||||||
|
// Create direct template.
|
||||||
|
const directTemplate = await seedDirectTemplate({
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: user.email,
|
||||||
|
redirectPath: '/settings/public-profile',
|
||||||
|
});
|
||||||
|
|
||||||
|
const publicProfileUrl = Date.now().toString();
|
||||||
|
const publicProfileBio = `public-profile-bio`;
|
||||||
|
|
||||||
|
await page.getByRole('textbox', { name: 'Public profile URL' }).click();
|
||||||
|
await page.getByRole('textbox', { name: 'Public profile URL' }).fill(publicProfileUrl);
|
||||||
|
|
||||||
|
await page.getByRole('textbox', { name: 'Bio' }).click();
|
||||||
|
await page.getByRole('textbox', { name: 'Bio' }).fill(publicProfileBio);
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Update' }).click();
|
||||||
|
|
||||||
|
await expect(page.getByRole('status').first()).toContainText(
|
||||||
|
'Your public profile has been updated.',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Link direct template to public profile.
|
||||||
|
await page.getByRole('button', { name: 'Link template' }).click();
|
||||||
|
await page.getByRole('cell', { name: directTemplate.title }).click();
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
|
||||||
|
await page.getByRole('textbox', { name: 'Title *' }).fill('public-direct-template-title');
|
||||||
|
await page
|
||||||
|
.getByRole('textbox', { name: 'Description *' })
|
||||||
|
.fill('public-direct-template-description');
|
||||||
|
await page.getByRole('button', { name: 'Update' }).click();
|
||||||
|
|
||||||
|
// Check that public profile is disabled.
|
||||||
|
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
|
||||||
|
await expect(page.locator('body')).toContainText('404 Profile not found');
|
||||||
|
|
||||||
|
// Go back to public profile page.
|
||||||
|
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/settings/public-profile`);
|
||||||
|
await page.getByRole('switch').click();
|
||||||
|
|
||||||
|
// Assert values.
|
||||||
|
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
|
||||||
|
await expect(page.getByRole('main')).toContainText(publicProfileBio);
|
||||||
|
await expect(page.locator('body')).toContainText('public-direct-template-title');
|
||||||
|
await expect(page.locator('body')).toContainText('public-direct-template-description');
|
||||||
|
|
||||||
|
await page.getByRole('link', { name: 'Sign' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Complete' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Sign' }).click();
|
||||||
|
|
||||||
|
await expect(page.getByRole('heading', { name: 'Document Signed' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('heading')).toContainText('Document Signed');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => {
|
||||||
|
const team = await seedTeam({
|
||||||
|
createTeamMembers: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = team.owner;
|
||||||
|
|
||||||
|
// Create direct template.
|
||||||
|
const directTemplate = await seedDirectTemplate({
|
||||||
|
userId: user.id,
|
||||||
|
teamId: team.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create non team template to make sure you can only see the team one.
|
||||||
|
// Will be indirectly asserted because test should fail when 2 elements appear.
|
||||||
|
await seedDirectTemplate({
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: user.email,
|
||||||
|
redirectPath: `/t/${team.url}/settings/public-profile`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const publicProfileUrl = team.url;
|
||||||
|
const publicProfileBio = `public-profile-bio`;
|
||||||
|
|
||||||
|
await page.getByRole('textbox', { name: 'Bio' }).click();
|
||||||
|
await page.getByRole('textbox', { name: 'Bio' }).fill(publicProfileBio);
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Update' }).click();
|
||||||
|
|
||||||
|
await expect(page.getByRole('status').first()).toContainText(
|
||||||
|
'Your public profile has been updated.',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Link direct template to public profile.
|
||||||
|
await page.getByRole('button', { name: 'Link template' }).click();
|
||||||
|
await page.getByRole('cell', { name: directTemplate.title }).click();
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
|
||||||
|
await page.getByRole('textbox', { name: 'Title *' }).fill('public-direct-template-title');
|
||||||
|
await page
|
||||||
|
.getByRole('textbox', { name: 'Description *' })
|
||||||
|
.fill('public-direct-template-description');
|
||||||
|
await page.getByRole('button', { name: 'Update' }).click();
|
||||||
|
|
||||||
|
// Check that public profile is disabled.
|
||||||
|
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
|
||||||
|
await expect(page.locator('body')).toContainText('404 Profile not found');
|
||||||
|
|
||||||
|
// Go back to public profile page.
|
||||||
|
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/settings/public-profile`);
|
||||||
|
await page.getByRole('switch').click();
|
||||||
|
|
||||||
|
// Assert values.
|
||||||
|
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
|
||||||
|
await expect(page.getByRole('main')).toContainText(publicProfileBio);
|
||||||
|
await expect(page.locator('body')).toContainText('public-direct-template-title');
|
||||||
|
await expect(page.locator('body')).toContainText('public-direct-template-description');
|
||||||
|
|
||||||
|
await page.getByRole('link', { name: 'Sign' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Complete' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Sign' }).click();
|
||||||
|
|
||||||
|
await expect(page.getByRole('heading', { name: 'Document Signed' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('heading')).toContainText('Document Signed');
|
||||||
|
});
|
||||||
@@ -30,10 +30,10 @@ const getAuthSecret = () => {
|
|||||||
export const sessionCookieOptions = {
|
export const sessionCookieOptions = {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: '/',
|
path: '/',
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax', // Todo: This feels wrong?
|
sameSite: useSecureCookies ? 'none' : 'lax', // Todo: (RR7) This feels wrong?
|
||||||
secure: useSecureCookies,
|
secure: useSecureCookies,
|
||||||
domain: getCookieDomain(),
|
domain: getCookieDomain(),
|
||||||
// Todo: Max age for specific auth cookies.
|
// Todo: (RR7) Max age for specific auth cookies.
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const extractSessionCookieFromHeaders = (headers: Headers): string | null => {
|
export const extractSessionCookieFromHeaders = (headers: Headers): string | null => {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export const getOptionalSession = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Todo: Rethink, this is pretty sketchy.
|
* Todo: (RR7) Rethink, this is pretty sketchy.
|
||||||
*/
|
*/
|
||||||
const mapRequestToContextForCookie = (c: Context | Request) => {
|
const mapRequestToContextForCookie = (c: Context | Request) => {
|
||||||
if (c instanceof Request) {
|
if (c instanceof Request) {
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export const handleOAuthCallbackUrl = async (options: HandleOAuthCallbackUrlOpti
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
emailVerified: new Date(),
|
emailVerified: new Date(),
|
||||||
password: null, // Todo: Check this
|
password: null, // Todo: (RR7) Check this
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ export const handleOAuthCallbackUrl = async (options: HandleOAuthCallbackUrlOpti
|
|||||||
});
|
});
|
||||||
|
|
||||||
await onCreateUserHook(createdUser).catch((err) => {
|
await onCreateUserHook(createdUser).catch((err) => {
|
||||||
// Todo: Add logging.
|
// Todo: (RR7) Add logging.
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
|||||||
|
|
||||||
const csrfCookieToken = await getCsrfCookie(c);
|
const csrfCookieToken = await getCsrfCookie(c);
|
||||||
|
|
||||||
// Todo: Add logging here.
|
// Todo: (RR7) Add logging here.
|
||||||
if (csrfToken !== csrfCookieToken || !csrfCookieToken) {
|
if (csrfToken !== csrfCookieToken || !csrfCookieToken) {
|
||||||
throw new AppError(AuthenticationErrorCode.InvalidRequest, {
|
throw new AppError(AuthenticationErrorCode.InvalidRequest, {
|
||||||
message: 'Invalid CSRF token',
|
message: 'Invalid CSRF token',
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export const stripeWebhookHandler = async (req: Request) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: I'm not sure about this.
|
// Todo: (RR7) I'm not sure about this.
|
||||||
const clonedReq = req.clone();
|
const clonedReq = req.clone();
|
||||||
const rawBody = await clonedReq.arrayBuffer();
|
const rawBody = await clonedReq.arrayBuffer();
|
||||||
const body = Buffer.from(rawBody);
|
const body = Buffer.from(rawBody);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export const useSession = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...context.sessionData,
|
...context.sessionData,
|
||||||
refresh: context.refresh,
|
refreshSession: context.refresh,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ export const SessionProvider = ({ children, initialSession }: SessionProviderPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
const teams = await trpc.team.getTeams.query().catch(() => {
|
const teams = await trpc.team.getTeams.query().catch(() => {
|
||||||
// Todo: Log
|
// Todo: (RR7) Log
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export class InngestJobProvider extends BaseJobProvider {
|
|||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Todo: Do we need to handle the above?
|
// Todo: (RR7) Do we need to handle the above?
|
||||||
public getApiHandler() {
|
public getApiHandler() {
|
||||||
return async (context: HonoContext) => {
|
return async (context: HonoContext) => {
|
||||||
const handler = createHonoPagesRoute({
|
const handler = createHonoPagesRoute({
|
||||||
|
|||||||
@@ -52,18 +52,18 @@ export const createUser = async ({ name, email, password, signature, url }: Crea
|
|||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
email: email.toLowerCase(),
|
email: email.toLowerCase(),
|
||||||
password: hashedPassword, // Todo: Drop password.
|
password: hashedPassword, // Todo: (RR7) Drop password.
|
||||||
signature,
|
signature,
|
||||||
url,
|
url,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Todo: Migrate to use this after RR7.
|
// Todo: (RR7) Migrate to use this after RR7.
|
||||||
// await tx.account.create({
|
// await tx.account.create({
|
||||||
// data: {
|
// data: {
|
||||||
// userId: user.id,
|
// userId: user.id,
|
||||||
// type: 'emailPassword', // Todo
|
// type: 'emailPassword', // Todo: (RR7)
|
||||||
// provider: 'DOCUMENSO', // Todo: Enums
|
// provider: 'DOCUMENSO', // Todo: (RR7) Enums
|
||||||
// providerAccountId: user.id.toString(),
|
// providerAccountId: user.id.toString(),
|
||||||
// password: hashedPassword,
|
// password: hashedPassword,
|
||||||
// },
|
// },
|
||||||
@@ -73,7 +73,7 @@ export const createUser = async ({ name, email, password, signature, url }: Crea
|
|||||||
});
|
});
|
||||||
|
|
||||||
await onCreateUserHook(user).catch((err) => {
|
await onCreateUserHook(user).catch((err) => {
|
||||||
// Todo: Add logging.
|
// Todo: (RR7) Add logging.
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ datasource db {
|
|||||||
directUrl = env("NEXT_PRIVATE_DIRECT_DATABASE_URL")
|
directUrl = env("NEXT_PRIVATE_DIRECT_DATABASE_URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Remove after RR7 migration.
|
// Todo: (RR7) Remove after RR7 migration.
|
||||||
enum IdentityProvider {
|
enum IdentityProvider {
|
||||||
DOCUMENSO
|
DOCUMENSO
|
||||||
GOOGLE
|
GOOGLE
|
||||||
@@ -41,14 +41,14 @@ model User {
|
|||||||
customerId String? @unique
|
customerId String? @unique
|
||||||
email String @unique
|
email String @unique
|
||||||
emailVerified DateTime?
|
emailVerified DateTime?
|
||||||
password String? // Todo: Remove after RR7 migration.
|
password String? // Todo: (RR7) Remove after RR7 migration.
|
||||||
source String?
|
source String?
|
||||||
signature String?
|
signature String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
lastSignedIn DateTime @default(now())
|
lastSignedIn DateTime @default(now())
|
||||||
roles Role[] @default([USER])
|
roles Role[] @default([USER])
|
||||||
identityProvider IdentityProvider @default(DOCUMENSO) // Todo: Remove after RR7 migration.
|
identityProvider IdentityProvider @default(DOCUMENSO) // Todo: (RR7) Remove after RR7 migration.
|
||||||
avatarImageId String?
|
avatarImageId String?
|
||||||
disabled Boolean @default(false)
|
disabled Boolean @default(false)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Todo: Not sure if this actually makes it client-only.
|
// Todo: (RR7) Not sure if this actually makes it client-only.
|
||||||
import { Suspense, lazy } from 'react';
|
import { Suspense, lazy } from 'react';
|
||||||
|
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
|
|||||||
Reference in New Issue
Block a user