mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 16:23:06 +10:00
chore: implemented feedback + a small refactoring
This commit is contained in:
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user