chore: implemented feedback + a small refactoring

This commit is contained in:
Catalin Pit
2023-12-11 14:33:30 +02:00
parent 66c0db91da
commit 8ecd8a7d10
6 changed files with 42 additions and 39 deletions

View File

@ -3,7 +3,7 @@ import { ApiTokenForm } from '~/components/forms/token';
export default function ApiToken() {
return (
<div>
<h3 className="text-lg font-medium">API Token</h3>
<h3 className="text-lg font-medium">API Tokens</h3>
<p className="text-muted-foreground mt-2 text-sm">
On this page, you can create new API tokens and manage the existing ones.

View File

@ -6,6 +6,7 @@ import { useRouter } from 'next/navigation';
import { zodResolver } from '@hookform/resolvers/zod';
import { Loader } from 'lucide-react';
import { DateTime } from 'luxon';
import { useForm } from 'react-hook-form';
import type { z } from 'zod';
@ -139,23 +140,13 @@ export const ApiTokenForm = ({ className }: ApiTokenFormProps) => {
<p className="text-sm">
Created:{' '}
{token.createdAt
? new Date(token.createdAt).toLocaleDateString(undefined, {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
})
? DateTime.fromJSDate(token.createdAt).toLocaleString(DateTime.DATETIME_FULL)
: 'N/A'}
</p>
<p className="mb-4 text-sm">
Expires:{' '}
{token.expires
? new Date(token.expires).toLocaleDateString(undefined, {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
})
? DateTime.fromJSDate(token.createdAt).toLocaleString(DateTime.DATETIME_FULL)
: 'N/A'}
</p>
<DeleteTokenDialog

View File

@ -12,27 +12,20 @@ import { getPresignPostUrl } from '@documenso/lib/universal/upload/server-action
import { contract } from '@documenso/trpc/api-contract/contract';
import { createNextRoute, createNextRouter } from '@documenso/trpc/server/public-api/ts-rest';
const validateUserToken = async (token: string) => {
try {
return await checkUserFromToken({ token });
} catch (e) {
return null;
}
};
const router = createNextRoute(contract, {
getDocuments: async (args) => {
const page = Number(args.query.page) || 1;
const perPage = Number(args.query.perPage) || 10;
const { authorization } = args.headers;
let user;
const user = await validateUserToken(authorization);
if (!user) {
try {
user = await checkUserFromToken({ token: authorization });
} catch (e) {
return {
status: 401,
body: {
message: 'Unauthorized',
message: e.message,
},
};
}
@ -50,14 +43,15 @@ const router = createNextRoute(contract, {
getDocument: async (args) => {
const { id: documentId } = args.params;
const { authorization } = args.headers;
let user;
const user = await validateUserToken(authorization);
if (!user) {
try {
user = await checkUserFromToken({ token: authorization });
} catch (e) {
return {
status: 401,
body: {
message: 'Unauthorized',
message: e.message,
},
};
}
@ -82,13 +76,15 @@ const router = createNextRoute(contract, {
const { id: documentId } = args.params;
const { authorization } = args.headers;
const user = await validateUserToken(authorization);
let user;
if (!user) {
try {
user = await checkUserFromToken({ token: authorization });
} catch (e) {
return {
status: 401,
body: {
message: 'Unauthorized',
message: e.message,
},
};
}
@ -141,14 +137,15 @@ const router = createNextRoute(contract, {
const { authorization } = args.headers;
const { id } = args.params;
const { body } = args;
let user;
const user = await validateUserToken(authorization);
if (!user) {
try {
user = await checkUserFromToken({ token: authorization });
} catch (e) {
return {
status: 401,
body: {
message: 'Unauthorized',
message: e.message,
},
};
}

View File

@ -3,3 +3,5 @@ export const ONE_MINUTE = ONE_SECOND * 60;
export const ONE_HOUR = ONE_MINUTE * 60;
export const ONE_DAY = ONE_HOUR * 24;
export const ONE_WEEK = ONE_DAY * 7;
export const ONE_MONTH = ONE_DAY * 30;
export const ONE_YEAR = ONE_DAY * 365;

View File

@ -3,7 +3,7 @@ import crypto from 'crypto';
import { prisma } from '@documenso/prisma';
// temporary choice for testing only
import { ONE_WEEK } from '../../constants/time';
import { ONE_YEAR } from '../../constants/time';
type CreateApiTokenInput = {
userId: number;
@ -22,7 +22,7 @@ export const createApiToken = async ({ userId, tokenName }: CreateApiTokenInput)
token: tokenHash,
name: tokenName,
userId,
expires: new Date(Date.now() + ONE_WEEK),
expires: new Date(Date.now() + ONE_YEAR),
},
});

View File

@ -1,7 +1,7 @@
import { prisma } from '@documenso/prisma';
export const checkUserFromToken = async ({ token }: { token: string }) => {
const user = await prisma.user.findFirstOrThrow({
const user = await prisma.user.findFirst({
where: {
ApiToken: {
some: {
@ -9,7 +9,20 @@ export const checkUserFromToken = async ({ token }: { token: string }) => {
},
},
},
include: {
ApiToken: true,
},
});
if (!user) {
throw new Error('Token not found');
}
const tokenObject = user.ApiToken.find((apiToken) => apiToken.token === token);
if (!tokenObject || new Date(tokenObject.expires) < new Date()) {
throw new Error('The API token has expired');
}
return user;
};