mirror of
https://github.com/documenso/documenso.git
synced 2026-07-25 09:25:08 +10:00
fix: refactor auth router (#1983)
This commit is contained in:
@@ -65,9 +65,9 @@ export const PasskeyCreateDialog = ({ trigger, onSuccess, ...props }: PasskeyCre
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { mutateAsync: createPasskeyRegistrationOptions, isPending } =
|
const { mutateAsync: createPasskeyRegistrationOptions, isPending } =
|
||||||
trpc.auth.createPasskeyRegistrationOptions.useMutation();
|
trpc.auth.passkey.createRegistrationOptions.useMutation();
|
||||||
|
|
||||||
const { mutateAsync: createPasskey } = trpc.auth.createPasskey.useMutation();
|
const { mutateAsync: createPasskey } = trpc.auth.passkey.create.useMutation();
|
||||||
|
|
||||||
const onFormSubmit = async ({ passkeyName }: TCreatePasskeyFormSchema) => {
|
const onFormSubmit = async ({ passkeyName }: TCreatePasskeyFormSchema) => {
|
||||||
setFormError(null);
|
setFormError(null);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ export const SignInForm = ({
|
|||||||
}, [returnTo]);
|
}, [returnTo]);
|
||||||
|
|
||||||
const { mutateAsync: createPasskeySigninOptions } =
|
const { mutateAsync: createPasskeySigninOptions } =
|
||||||
trpc.auth.createPasskeySigninOptions.useMutation();
|
trpc.auth.passkey.createSigninOptions.useMutation();
|
||||||
|
|
||||||
const form = useForm<TSignInFormSchema>({
|
const form = useForm<TSignInFormSchema>({
|
||||||
values: {
|
values: {
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ export const DocumentSigningAuthPasskey = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { mutateAsync: createPasskeyAuthenticationOptions } =
|
const { mutateAsync: createPasskeyAuthenticationOptions } =
|
||||||
trpc.auth.createPasskeyAuthenticationOptions.useMutation();
|
trpc.auth.passkey.createAuthenticationOptions.useMutation();
|
||||||
|
|
||||||
const [formErrorCode, setFormErrorCode] = useState<string | null>(null);
|
const [formErrorCode, setFormErrorCode] = useState<string | null>(null);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ export const DocumentSigningAuthProvider = ({
|
|||||||
[documentAuthOptions, recipient],
|
[documentAuthOptions, recipient],
|
||||||
);
|
);
|
||||||
|
|
||||||
const passkeyQuery = trpc.auth.findPasskeys.useQuery(
|
const passkeyQuery = trpc.auth.passkey.find.useQuery(
|
||||||
{
|
{
|
||||||
perPage: MAXIMUM_PASSKEYS,
|
perPage: MAXIMUM_PASSKEYS,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const SettingsSecurityPasskeyTableActions = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { mutateAsync: updatePasskey, isPending: isUpdatingPasskey } =
|
const { mutateAsync: updatePasskey, isPending: isUpdatingPasskey } =
|
||||||
trpc.auth.updatePasskey.useMutation({
|
trpc.auth.passkey.update.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast({
|
toast({
|
||||||
title: _(msg`Success`),
|
title: _(msg`Success`),
|
||||||
@@ -84,7 +84,7 @@ export const SettingsSecurityPasskeyTableActions = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { mutateAsync: deletePasskey, isPending: isDeletingPasskey } =
|
const { mutateAsync: deletePasskey, isPending: isDeletingPasskey } =
|
||||||
trpc.auth.deletePasskey.useMutation({
|
trpc.auth.passkey.delete.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast({
|
toast({
|
||||||
title: _(msg`Success`),
|
title: _(msg`Success`),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const SettingsSecurityPasskeyTable = () => {
|
|||||||
|
|
||||||
const parsedSearchParams = ZUrlSearchParamsSchema.parse(Object.fromEntries(searchParams ?? []));
|
const parsedSearchParams = ZUrlSearchParamsSchema.parse(Object.fromEntries(searchParams ?? []));
|
||||||
|
|
||||||
const { data, isLoading, isLoadingError } = trpc.auth.findPasskeys.useQuery(
|
const { data, isLoading, isLoadingError } = trpc.auth.passkey.find.useQuery(
|
||||||
{
|
{
|
||||||
page: parsedSearchParams.page,
|
page: parsedSearchParams.page,
|
||||||
perPage: parsedSearchParams.perPage,
|
perPage: parsedSearchParams.perPage,
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { createPasskeyAuthenticationOptions } from '@documenso/lib/server-only/auth/create-passkey-authentication-options';
|
||||||
|
|
||||||
|
import { authenticatedProcedure } from '../trpc';
|
||||||
|
import {
|
||||||
|
ZCreatePasskeyAuthenticationOptionsRequestSchema,
|
||||||
|
ZCreatePasskeyAuthenticationOptionsResponseSchema,
|
||||||
|
} from './create-passkey-authentication-options.types';
|
||||||
|
|
||||||
|
export const createPasskeyAuthenticationOptionsRoute = authenticatedProcedure
|
||||||
|
.input(ZCreatePasskeyAuthenticationOptionsRequestSchema)
|
||||||
|
.output(ZCreatePasskeyAuthenticationOptionsResponseSchema)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
return await createPasskeyAuthenticationOptions({
|
||||||
|
userId: ctx.user.id,
|
||||||
|
preferredPasskeyId: input?.preferredPasskeyId,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const ZCreatePasskeyAuthenticationOptionsRequestSchema = z
|
||||||
|
.object({
|
||||||
|
preferredPasskeyId: z.string().optional(),
|
||||||
|
})
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
export const ZCreatePasskeyAuthenticationOptionsResponseSchema = z.object({
|
||||||
|
tokenReference: z.string(),
|
||||||
|
options: z.any(), // PublicKeyCredentialRequestOptions type
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TCreatePasskeyAuthenticationOptionsRequest = z.infer<
|
||||||
|
typeof ZCreatePasskeyAuthenticationOptionsRequestSchema
|
||||||
|
>;
|
||||||
|
export type TCreatePasskeyAuthenticationOptionsResponse = z.infer<
|
||||||
|
typeof ZCreatePasskeyAuthenticationOptionsResponseSchema
|
||||||
|
>;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { createPasskeyRegistrationOptions } from '@documenso/lib/server-only/auth/create-passkey-registration-options';
|
||||||
|
|
||||||
|
import { authenticatedProcedure } from '../trpc';
|
||||||
|
import {
|
||||||
|
ZCreatePasskeyRegistrationOptionsRequestSchema,
|
||||||
|
ZCreatePasskeyRegistrationOptionsResponseSchema,
|
||||||
|
} from './create-passkey-registration-options.types';
|
||||||
|
|
||||||
|
export const createPasskeyRegistrationOptionsRoute = authenticatedProcedure
|
||||||
|
.input(ZCreatePasskeyRegistrationOptionsRequestSchema)
|
||||||
|
.output(ZCreatePasskeyRegistrationOptionsResponseSchema)
|
||||||
|
.mutation(async ({ ctx }) => {
|
||||||
|
return await createPasskeyRegistrationOptions({
|
||||||
|
userId: ctx.user.id,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const ZCreatePasskeyRegistrationOptionsRequestSchema = z.void();
|
||||||
|
|
||||||
|
export const ZCreatePasskeyRegistrationOptionsResponseSchema = z.any(); // PublicKeyCredentialCreationOptions type
|
||||||
|
|
||||||
|
export type TCreatePasskeyRegistrationOptionsRequest = z.infer<
|
||||||
|
typeof ZCreatePasskeyRegistrationOptionsRequestSchema
|
||||||
|
>;
|
||||||
|
export type TCreatePasskeyRegistrationOptionsResponse = z.infer<
|
||||||
|
typeof ZCreatePasskeyRegistrationOptionsResponseSchema
|
||||||
|
>;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { createPasskeySigninOptions } from '@documenso/lib/server-only/auth/create-passkey-signin-options';
|
||||||
|
import { nanoid } from '@documenso/lib/universal/id';
|
||||||
|
|
||||||
|
import { procedure } from '../trpc';
|
||||||
|
import {
|
||||||
|
ZCreatePasskeySigninOptionsRequestSchema,
|
||||||
|
ZCreatePasskeySigninOptionsResponseSchema,
|
||||||
|
} from './create-passkey-signin-options.types';
|
||||||
|
|
||||||
|
export const createPasskeySigninOptionsRoute = procedure
|
||||||
|
.input(ZCreatePasskeySigninOptionsRequestSchema)
|
||||||
|
.output(ZCreatePasskeySigninOptionsResponseSchema)
|
||||||
|
.mutation(async () => {
|
||||||
|
const sessionIdToken = nanoid(16);
|
||||||
|
|
||||||
|
const [sessionId] = decodeURI(sessionIdToken).split('|');
|
||||||
|
|
||||||
|
const options = await createPasskeySigninOptions({ sessionId });
|
||||||
|
|
||||||
|
return {
|
||||||
|
options,
|
||||||
|
sessionId,
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const ZCreatePasskeySigninOptionsRequestSchema = z.void();
|
||||||
|
|
||||||
|
export const ZCreatePasskeySigninOptionsResponseSchema = z.object({
|
||||||
|
options: z.any(), // PublicKeyCredentialRequestOptions type
|
||||||
|
sessionId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TCreatePasskeySigninOptionsRequest = z.infer<
|
||||||
|
typeof ZCreatePasskeySigninOptionsRequestSchema
|
||||||
|
>;
|
||||||
|
export type TCreatePasskeySigninOptionsResponse = z.infer<
|
||||||
|
typeof ZCreatePasskeySigninOptionsResponseSchema
|
||||||
|
>;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import type { RegistrationResponseJSON } from '@simplewebauthn/types';
|
||||||
|
|
||||||
|
import { createPasskey } from '@documenso/lib/server-only/auth/create-passkey';
|
||||||
|
|
||||||
|
import { authenticatedProcedure } from '../trpc';
|
||||||
|
import { ZCreatePasskeyRequestSchema, ZCreatePasskeyResponseSchema } from './create-passkey.types';
|
||||||
|
|
||||||
|
export const createPasskeyRoute = authenticatedProcedure
|
||||||
|
.input(ZCreatePasskeyRequestSchema)
|
||||||
|
.output(ZCreatePasskeyResponseSchema)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
|
const verificationResponse = input.verificationResponse as RegistrationResponseJSON;
|
||||||
|
|
||||||
|
return await createPasskey({
|
||||||
|
userId: ctx.user.id,
|
||||||
|
verificationResponse,
|
||||||
|
passkeyName: input.passkeyName,
|
||||||
|
requestMetadata: ctx.metadata.requestMetadata,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { ZRegistrationResponseJSONSchema } from '@documenso/lib/types/webauthn';
|
||||||
|
|
||||||
|
export const ZCreatePasskeyRequestSchema = z.object({
|
||||||
|
passkeyName: z.string().trim().min(1),
|
||||||
|
verificationResponse: ZRegistrationResponseJSONSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ZCreatePasskeyResponseSchema = z.void();
|
||||||
|
|
||||||
|
export type TCreatePasskeyRequest = z.infer<typeof ZCreatePasskeyRequestSchema>;
|
||||||
|
export type TCreatePasskeyResponse = z.infer<typeof ZCreatePasskeyResponseSchema>;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { deletePasskey } from '@documenso/lib/server-only/auth/delete-passkey';
|
||||||
|
|
||||||
|
import { authenticatedProcedure } from '../trpc';
|
||||||
|
import { ZDeletePasskeyRequestSchema, ZDeletePasskeyResponseSchema } from './delete-passkey.types';
|
||||||
|
|
||||||
|
export const deletePasskeyRoute = authenticatedProcedure
|
||||||
|
.input(ZDeletePasskeyRequestSchema)
|
||||||
|
.output(ZDeletePasskeyResponseSchema)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const { passkeyId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
passkeyId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await deletePasskey({
|
||||||
|
userId: ctx.user.id,
|
||||||
|
passkeyId,
|
||||||
|
requestMetadata: ctx.metadata.requestMetadata,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const ZDeletePasskeyRequestSchema = z.object({
|
||||||
|
passkeyId: z.string().trim().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ZDeletePasskeyResponseSchema = z.void();
|
||||||
|
|
||||||
|
export type TDeletePasskeyRequest = z.infer<typeof ZDeletePasskeyRequestSchema>;
|
||||||
|
export type TDeletePasskeyResponse = z.infer<typeof ZDeletePasskeyResponseSchema>;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { findPasskeys } from '@documenso/lib/server-only/auth/find-passkeys';
|
||||||
|
|
||||||
|
import { authenticatedProcedure } from '../trpc';
|
||||||
|
import { ZFindPasskeysRequestSchema, ZFindPasskeysResponseSchema } from './find-passkeys.types';
|
||||||
|
|
||||||
|
export const findPasskeysRoute = authenticatedProcedure
|
||||||
|
.input(ZFindPasskeysRequestSchema)
|
||||||
|
.output(ZFindPasskeysResponseSchema)
|
||||||
|
.query(async ({ input, ctx }) => {
|
||||||
|
const { page, perPage, orderBy } = input;
|
||||||
|
|
||||||
|
return await findPasskeys({
|
||||||
|
page,
|
||||||
|
perPage,
|
||||||
|
orderBy,
|
||||||
|
userId: ctx.user.id,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params';
|
||||||
|
import PasskeySchema from '@documenso/prisma/generated/zod/modelSchema/PasskeySchema';
|
||||||
|
|
||||||
|
export const ZFindPasskeysRequestSchema = ZFindSearchParamsSchema.extend({
|
||||||
|
orderBy: z
|
||||||
|
.object({
|
||||||
|
column: z.enum(['createdAt', 'updatedAt', 'name']),
|
||||||
|
direction: z.enum(['asc', 'desc']),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ZFindPasskeysResponseSchema = ZFindResultResponse.extend({
|
||||||
|
data: z.array(
|
||||||
|
PasskeySchema.pick({
|
||||||
|
id: true,
|
||||||
|
userId: true,
|
||||||
|
name: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: true,
|
||||||
|
lastUsedAt: true,
|
||||||
|
counter: true,
|
||||||
|
credentialDeviceType: true,
|
||||||
|
credentialBackedUp: true,
|
||||||
|
transports: true,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TFindPasskeysRequest = z.infer<typeof ZFindPasskeysRequestSchema>;
|
||||||
|
export type TFindPasskeysResponse = z.infer<typeof ZFindPasskeysResponseSchema>;
|
||||||
@@ -1,113 +1,20 @@
|
|||||||
import type { RegistrationResponseJSON } from '@simplewebauthn/types';
|
import { router } from '../trpc';
|
||||||
|
import { createPasskeyRoute } from './create-passkey';
|
||||||
import { createPasskey } from '@documenso/lib/server-only/auth/create-passkey';
|
import { createPasskeyAuthenticationOptionsRoute } from './create-passkey-authentication-options';
|
||||||
import { createPasskeyAuthenticationOptions } from '@documenso/lib/server-only/auth/create-passkey-authentication-options';
|
import { createPasskeyRegistrationOptionsRoute } from './create-passkey-registration-options';
|
||||||
import { createPasskeyRegistrationOptions } from '@documenso/lib/server-only/auth/create-passkey-registration-options';
|
import { createPasskeySigninOptionsRoute } from './create-passkey-signin-options';
|
||||||
import { createPasskeySigninOptions } from '@documenso/lib/server-only/auth/create-passkey-signin-options';
|
import { deletePasskeyRoute } from './delete-passkey';
|
||||||
import { deletePasskey } from '@documenso/lib/server-only/auth/delete-passkey';
|
import { findPasskeysRoute } from './find-passkeys';
|
||||||
import { findPasskeys } from '@documenso/lib/server-only/auth/find-passkeys';
|
import { updatePasskeyRoute } from './update-passkey';
|
||||||
import { updatePasskey } from '@documenso/lib/server-only/auth/update-passkey';
|
|
||||||
import { nanoid } from '@documenso/lib/universal/id';
|
|
||||||
|
|
||||||
import { authenticatedProcedure, procedure, router } from '../trpc';
|
|
||||||
import {
|
|
||||||
ZCreatePasskeyAuthenticationOptionsMutationSchema,
|
|
||||||
ZCreatePasskeyMutationSchema,
|
|
||||||
ZDeletePasskeyMutationSchema,
|
|
||||||
ZFindPasskeysQuerySchema,
|
|
||||||
ZUpdatePasskeyMutationSchema,
|
|
||||||
} from './schema';
|
|
||||||
|
|
||||||
export const authRouter = router({
|
export const authRouter = router({
|
||||||
createPasskey: authenticatedProcedure
|
passkey: router({
|
||||||
.input(ZCreatePasskeyMutationSchema)
|
create: createPasskeyRoute,
|
||||||
.mutation(async ({ ctx, input }) => {
|
createAuthenticationOptions: createPasskeyAuthenticationOptionsRoute,
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
createRegistrationOptions: createPasskeyRegistrationOptionsRoute,
|
||||||
const verificationResponse = input.verificationResponse as RegistrationResponseJSON;
|
createSigninOptions: createPasskeySigninOptionsRoute,
|
||||||
|
delete: deletePasskeyRoute,
|
||||||
return await createPasskey({
|
find: findPasskeysRoute,
|
||||||
userId: ctx.user.id,
|
update: updatePasskeyRoute,
|
||||||
verificationResponse,
|
|
||||||
passkeyName: input.passkeyName,
|
|
||||||
requestMetadata: ctx.metadata.requestMetadata,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
createPasskeyAuthenticationOptions: authenticatedProcedure
|
|
||||||
.input(ZCreatePasskeyAuthenticationOptionsMutationSchema)
|
|
||||||
.mutation(async ({ ctx, input }) => {
|
|
||||||
return await createPasskeyAuthenticationOptions({
|
|
||||||
userId: ctx.user.id,
|
|
||||||
preferredPasskeyId: input?.preferredPasskeyId,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
createPasskeyRegistrationOptions: authenticatedProcedure.mutation(async ({ ctx }) => {
|
|
||||||
return await createPasskeyRegistrationOptions({
|
|
||||||
userId: ctx.user.id,
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createPasskeySigninOptions: procedure.mutation(async () => {
|
|
||||||
const sessionIdToken = nanoid(16);
|
|
||||||
|
|
||||||
const [sessionId] = decodeURI(sessionIdToken).split('|');
|
|
||||||
|
|
||||||
const options = await createPasskeySigninOptions({ sessionId });
|
|
||||||
|
|
||||||
return {
|
|
||||||
options,
|
|
||||||
sessionId,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
|
|
||||||
deletePasskey: authenticatedProcedure
|
|
||||||
.input(ZDeletePasskeyMutationSchema)
|
|
||||||
.mutation(async ({ ctx, input }) => {
|
|
||||||
const { passkeyId } = input;
|
|
||||||
|
|
||||||
ctx.logger.info({
|
|
||||||
input: {
|
|
||||||
passkeyId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await deletePasskey({
|
|
||||||
userId: ctx.user.id,
|
|
||||||
passkeyId,
|
|
||||||
requestMetadata: ctx.metadata.requestMetadata,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
findPasskeys: authenticatedProcedure
|
|
||||||
.input(ZFindPasskeysQuerySchema)
|
|
||||||
.query(async ({ input, ctx }) => {
|
|
||||||
const { page, perPage, orderBy } = input;
|
|
||||||
|
|
||||||
return await findPasskeys({
|
|
||||||
page,
|
|
||||||
perPage,
|
|
||||||
orderBy,
|
|
||||||
userId: ctx.user.id,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
updatePasskey: authenticatedProcedure
|
|
||||||
.input(ZUpdatePasskeyMutationSchema)
|
|
||||||
.mutation(async ({ ctx, input }) => {
|
|
||||||
const { passkeyId, name } = input;
|
|
||||||
|
|
||||||
ctx.logger.info({
|
|
||||||
input: {
|
|
||||||
passkeyId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await updatePasskey({
|
|
||||||
userId: ctx.user.id,
|
|
||||||
passkeyId,
|
|
||||||
name,
|
|
||||||
requestMetadata: ctx.metadata.requestMetadata,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { ZFindSearchParamsSchema } from '@documenso/lib/types/search-params';
|
|
||||||
import { ZRegistrationResponseJSONSchema } from '@documenso/lib/types/webauthn';
|
|
||||||
|
|
||||||
export const ZCurrentPasswordSchema = z
|
export const ZCurrentPasswordSchema = z
|
||||||
.string()
|
.string()
|
||||||
.min(6, { message: 'Must be at least 6 characters in length' })
|
.min(6, { message: 'Must be at least 6 characters in length' })
|
||||||
@@ -24,50 +21,3 @@ export const ZPasswordSchema = z
|
|||||||
.refine((value) => value.length > 25 || /[`~<>?,./!@#$%^&*()\-_"'+=|{}[\];:\\]/.test(value), {
|
.refine((value) => value.length > 25 || /[`~<>?,./!@#$%^&*()\-_"'+=|{}[\];:\\]/.test(value), {
|
||||||
message: 'One special character is required',
|
message: 'One special character is required',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ZSignUpMutationSchema = z.object({
|
|
||||||
name: z.string().min(1),
|
|
||||||
email: z.string().email(),
|
|
||||||
password: ZPasswordSchema,
|
|
||||||
signature: z.string().nullish(),
|
|
||||||
url: z
|
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
.min(1)
|
|
||||||
.regex(/^[a-z0-9-]+$/, {
|
|
||||||
message: 'Username can only container alphanumeric characters and dashes.',
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ZCreatePasskeyMutationSchema = z.object({
|
|
||||||
passkeyName: z.string().trim().min(1),
|
|
||||||
verificationResponse: ZRegistrationResponseJSONSchema,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ZCreatePasskeyAuthenticationOptionsMutationSchema = z
|
|
||||||
.object({
|
|
||||||
preferredPasskeyId: z.string().optional(),
|
|
||||||
})
|
|
||||||
.optional();
|
|
||||||
|
|
||||||
export const ZDeletePasskeyMutationSchema = z.object({
|
|
||||||
passkeyId: z.string().trim().min(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ZUpdatePasskeyMutationSchema = z.object({
|
|
||||||
passkeyId: z.string().trim().min(1),
|
|
||||||
name: z.string().trim().min(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ZFindPasskeysQuerySchema = ZFindSearchParamsSchema.extend({
|
|
||||||
orderBy: z
|
|
||||||
.object({
|
|
||||||
column: z.enum(['createdAt', 'updatedAt', 'name']),
|
|
||||||
direction: z.enum(['asc', 'desc']),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type TSignUpMutationSchema = z.infer<typeof ZSignUpMutationSchema>;
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { updatePasskey } from '@documenso/lib/server-only/auth/update-passkey';
|
||||||
|
|
||||||
|
import { authenticatedProcedure } from '../trpc';
|
||||||
|
import { ZUpdatePasskeyRequestSchema, ZUpdatePasskeyResponseSchema } from './update-passkey.types';
|
||||||
|
|
||||||
|
export const updatePasskeyRoute = authenticatedProcedure
|
||||||
|
.input(ZUpdatePasskeyRequestSchema)
|
||||||
|
.output(ZUpdatePasskeyResponseSchema)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const { passkeyId, name } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
passkeyId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await updatePasskey({
|
||||||
|
userId: ctx.user.id,
|
||||||
|
passkeyId,
|
||||||
|
name,
|
||||||
|
requestMetadata: ctx.metadata.requestMetadata,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const ZUpdatePasskeyRequestSchema = z.object({
|
||||||
|
passkeyId: z.string().trim().min(1),
|
||||||
|
name: z.string().trim().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ZUpdatePasskeyResponseSchema = z.void();
|
||||||
|
|
||||||
|
export type TUpdatePasskeyRequest = z.infer<typeof ZUpdatePasskeyRequestSchema>;
|
||||||
|
export type TUpdatePasskeyResponse = z.infer<typeof ZUpdatePasskeyResponseSchema>;
|
||||||
Reference in New Issue
Block a user