feat: new embed method
This commit is contained in:
parent
e94dd58542
commit
388713a3c6
8 changed files with 76 additions and 63 deletions
13
prisma/migrations/20230111055303_embed/migration.sql
Normal file
13
prisma/migrations/20230111055303_embed/migration.sql
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `embedColor` on the `User` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `embedSiteName` on the `User` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `embedTitle` on the `User` table. All the data in the column will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" DROP COLUMN "embedColor",
|
||||||
|
DROP COLUMN "embedSiteName",
|
||||||
|
DROP COLUMN "embedTitle",
|
||||||
|
ADD COLUMN "embed" JSONB NOT NULL DEFAULT '{}';
|
|
@ -16,9 +16,7 @@ model User {
|
||||||
administrator Boolean @default(false)
|
administrator Boolean @default(false)
|
||||||
superAdmin Boolean @default(false)
|
superAdmin Boolean @default(false)
|
||||||
systemTheme String @default("system")
|
systemTheme String @default("system")
|
||||||
embedTitle String?
|
embed Json @default("{}")
|
||||||
embedColor String @default("#2f3136")
|
|
||||||
embedSiteName String? @default("{image.file} • {user.name}")
|
|
||||||
ratelimit DateTime?
|
ratelimit DateTime?
|
||||||
totpSecret String?
|
totpSecret String?
|
||||||
domains String[]
|
domains String[]
|
||||||
|
@ -48,7 +46,7 @@ model Image {
|
||||||
password String?
|
password String?
|
||||||
invisible InvisibleImage?
|
invisible InvisibleImage?
|
||||||
format ImageFormat @default(RANDOM)
|
format ImageFormat @default(RANDOM)
|
||||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||||
userId Int?
|
userId Int?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
Group,
|
Group,
|
||||||
Image,
|
Image,
|
||||||
PasswordInput,
|
PasswordInput,
|
||||||
|
SimpleGrid,
|
||||||
Space,
|
Space,
|
||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
|
@ -139,9 +140,10 @@ export default function Manage({ oauth_registration, oauth_providers: raw_oauth_
|
||||||
initialValues: {
|
initialValues: {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
password: '',
|
password: '',
|
||||||
embedTitle: user.embedTitle ?? '',
|
embedTitle: user.embed?.title ?? null,
|
||||||
embedColor: user.embedColor,
|
embedColor: user.embed?.color ?? '',
|
||||||
embedSiteName: user.embedSiteName ?? '',
|
embedSiteName: user.embed?.siteName ?? null,
|
||||||
|
embedDescription: user.embed?.description ?? null,
|
||||||
domains: user.domains.join(','),
|
domains: user.domains.join(','),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -149,9 +151,12 @@ export default function Manage({ oauth_registration, oauth_providers: raw_oauth_
|
||||||
const onSubmit = async (values) => {
|
const onSubmit = async (values) => {
|
||||||
const cleanUsername = values.username.trim();
|
const cleanUsername = values.username.trim();
|
||||||
const cleanPassword = values.password.trim();
|
const cleanPassword = values.password.trim();
|
||||||
const cleanEmbedTitle = values.embedTitle.trim();
|
const cleanEmbed = {
|
||||||
const cleanEmbedColor = values.embedColor.trim();
|
title: values.embedTitle ? values.embedTitle.trim() : null,
|
||||||
const cleanEmbedSiteName = values.embedSiteName.trim();
|
color: values.embedColor !== '' ? values.embedColor.trim() : null,
|
||||||
|
siteName: values.embedSiteName ? values.embedSiteName.trim() : null,
|
||||||
|
description: values.embedDescription ? values.embedDescription.trim() : null,
|
||||||
|
};
|
||||||
|
|
||||||
if (cleanUsername === '') return form.setFieldError('username', "Username can't be nothing");
|
if (cleanUsername === '') return form.setFieldError('username', "Username can't be nothing");
|
||||||
|
|
||||||
|
@ -166,13 +171,11 @@ export default function Manage({ oauth_registration, oauth_providers: raw_oauth_
|
||||||
const data = {
|
const data = {
|
||||||
username: cleanUsername,
|
username: cleanUsername,
|
||||||
password: cleanPassword === '' ? null : cleanPassword,
|
password: cleanPassword === '' ? null : cleanPassword,
|
||||||
embedTitle: cleanEmbedTitle === '' ? null : cleanEmbedTitle,
|
|
||||||
embedColor: cleanEmbedColor === '' ? null : cleanEmbedColor,
|
|
||||||
embedSiteName: cleanEmbedSiteName === '' ? null : cleanEmbedSiteName,
|
|
||||||
domains: values.domains
|
domains: values.domains
|
||||||
.split(/\s?,\s?/)
|
.split(/\s?,\s?/)
|
||||||
.map((x) => x.trim())
|
.map((x) => x.trim())
|
||||||
.filter((x) => x !== ''),
|
.filter((x) => x !== ''),
|
||||||
|
embed: cleanEmbed,
|
||||||
};
|
};
|
||||||
|
|
||||||
const newUser = await useFetch('/api/user', 'PATCH', data);
|
const newUser = await useFetch('/api/user', 'PATCH', data);
|
||||||
|
@ -405,14 +408,31 @@ export default function Manage({ oauth_registration, oauth_providers: raw_oauth_
|
||||||
my='sm'
|
my='sm'
|
||||||
{...form.getInputProps('password')}
|
{...form.getInputProps('password')}
|
||||||
/>
|
/>
|
||||||
<TextInput id='embedTitle' label='Embed Title' my='sm' {...form.getInputProps('embedTitle')} />
|
|
||||||
<ColorInput id='embedColor' label='Embed Color' my='sm' {...form.getInputProps('embedColor')} />
|
<SimpleGrid
|
||||||
<TextInput
|
cols={4}
|
||||||
id='embedSiteName'
|
breakpoints={[
|
||||||
label='Embed Site Name'
|
{ maxWidth: 768, cols: 1 },
|
||||||
my='sm'
|
{ minWidth: 769, maxWidth: 1024, cols: 2 },
|
||||||
{...form.getInputProps('embedSiteName')}
|
{ minWidth: 1281, cols: 4 },
|
||||||
/>
|
]}
|
||||||
|
>
|
||||||
|
<TextInput id='embedTitle' label='Embed Title' my='sm' {...form.getInputProps('embedTitle')} />
|
||||||
|
<ColorInput id='embedColor' label='Embed Color' my='sm' {...form.getInputProps('embedColor')} />
|
||||||
|
<TextInput
|
||||||
|
id='embedSiteName'
|
||||||
|
label='Embed Site Name'
|
||||||
|
my='sm'
|
||||||
|
{...form.getInputProps('embedSiteName')}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id='embedDescription'
|
||||||
|
label='Embed Description'
|
||||||
|
my='sm'
|
||||||
|
{...form.getInputProps('embedDescription')}
|
||||||
|
/>
|
||||||
|
</SimpleGrid>
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
id='domains'
|
id='domains'
|
||||||
label='Domains'
|
label='Domains'
|
||||||
|
|
|
@ -18,9 +18,19 @@ export interface NextApiFile {
|
||||||
size: number;
|
size: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserExtended extends User {
|
export interface UserOauth extends User {
|
||||||
oauth: OAuth[];
|
oauth: OAuth[];
|
||||||
}
|
}
|
||||||
|
export type UserExtended = UserOauth & {
|
||||||
|
embed: UserEmbed;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface UserEmbed {
|
||||||
|
title?: string;
|
||||||
|
siteName?: string;
|
||||||
|
description?: string;
|
||||||
|
color?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type NextApiReq = NextApiRequest & {
|
export type NextApiReq = NextApiRequest & {
|
||||||
user: () => Promise<UserExtended | null>;
|
user: () => Promise<UserExtended | null>;
|
||||||
|
@ -166,7 +176,7 @@ export const withZipline =
|
||||||
include: { oauth: true },
|
include: { oauth: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user) return user;
|
if (user) return user as UserExtended;
|
||||||
}
|
}
|
||||||
|
|
||||||
const userId = req.getCookie('user');
|
const userId = req.getCookie('user');
|
||||||
|
@ -182,7 +192,7 @@ export const withZipline =
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) return null;
|
if (!user) return null;
|
||||||
return user;
|
return user as UserExtended;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.get('withZipline').debug(e.message);
|
Logger.get('withZipline').debug(e.message);
|
||||||
if (e.code && e.code === 'ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH') {
|
if (e.code && e.code === 'ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH') {
|
||||||
|
|
|
@ -101,22 +101,10 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) {
|
||||||
data: { avatar: req.body.avatar },
|
data: { avatar: req.body.avatar },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (req.body.embedTitle)
|
if (req.body.embed)
|
||||||
await prisma.user.update({
|
await prisma.user.update({
|
||||||
where: { id: target.id },
|
where: { id: target.id },
|
||||||
data: { embedTitle: req.body.embedTitle },
|
data: { embed: req.body.embed },
|
||||||
});
|
|
||||||
|
|
||||||
if (req.body.embedColor)
|
|
||||||
await prisma.user.update({
|
|
||||||
where: { id: target.id },
|
|
||||||
data: { embedColor: req.body.embedColor },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (req.body.embedSiteName)
|
|
||||||
await prisma.user.update({
|
|
||||||
where: { id: target.id },
|
|
||||||
data: { embedSiteName: req.body.embedSiteName },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (req.body.systemTheme)
|
if (req.body.systemTheme)
|
||||||
|
|
|
@ -165,22 +165,10 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) {
|
||||||
data: { avatar: req.body.avatar },
|
data: { avatar: req.body.avatar },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (req.body.embedTitle)
|
if (req.body.embed)
|
||||||
await prisma.user.update({
|
await prisma.user.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
data: { embedTitle: req.body.embedTitle },
|
data: { embed: req.body.embed },
|
||||||
});
|
|
||||||
|
|
||||||
if (req.body.embedColor)
|
|
||||||
await prisma.user.update({
|
|
||||||
where: { id: user.id },
|
|
||||||
data: { embedColor: req.body.embedColor },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (req.body.embedSiteName)
|
|
||||||
await prisma.user.update({
|
|
||||||
where: { id: user.id },
|
|
||||||
data: { embedSiteName: req.body.embedSiteName },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (req.body.systemTheme)
|
if (req.body.systemTheme)
|
||||||
|
@ -222,9 +210,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) {
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
administrator: true,
|
administrator: true,
|
||||||
embedColor: true,
|
embed: true,
|
||||||
embedTitle: true,
|
|
||||||
embedSiteName: true,
|
|
||||||
id: true,
|
id: true,
|
||||||
images: false,
|
images: false,
|
||||||
password: false,
|
password: false,
|
||||||
|
|
|
@ -75,16 +75,16 @@ export default function EmbeddedFile({
|
||||||
<Head>
|
<Head>
|
||||||
{image.embed && (
|
{image.embed && (
|
||||||
<>
|
<>
|
||||||
{user.embedSiteName && (
|
{user.embed.siteName && (
|
||||||
<meta
|
<meta
|
||||||
property='og:site_name'
|
property='og:site_name'
|
||||||
content={parseString(user.embedSiteName, { file: image, user })}
|
content={parseString(user.embed.siteName, { file: image, user })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{user.embedTitle && (
|
{user.embed.title && (
|
||||||
<meta property='og:title' content={parseString(user.embedTitle, { file: image, user })} />
|
<meta property='og:title' content={parseString(user.embed.title, { file: image, user })} />
|
||||||
)}
|
)}
|
||||||
<meta property='theme-color' content={user.embedColor ?? '#2f3136'} />
|
<meta property='theme-color' content={user.embed.color ?? '#2f3136'} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{image.mimetype.startsWith('image') && (
|
{image.mimetype.startsWith('image') && (
|
||||||
|
|
|
@ -11,9 +11,7 @@ const SUPPORTED_FIELDS = [
|
||||||
'token',
|
'token',
|
||||||
'superAdmin',
|
'superAdmin',
|
||||||
'systemTheme',
|
'systemTheme',
|
||||||
'embedTitle',
|
'embed',
|
||||||
'embedColor',
|
|
||||||
'embedSiteName',
|
|
||||||
'ratelimit',
|
'ratelimit',
|
||||||
'domains',
|
'domains',
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue