Merge branch 'trunk' into feature/oauth-authentik

This commit is contained in:
dicedtomato 2023-05-22 15:31:39 -07:00 committed by GitHub
commit d5aaa51c7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 27 additions and 10 deletions

View file

@ -120,6 +120,8 @@ export interface ConfigFeatures {
headless: boolean; headless: boolean;
default_avatar: string; default_avatar: string;
robots_txt: string;
} }
export interface ConfigOAuth { export interface ConfigOAuth {

View file

@ -164,6 +164,8 @@ export default function readConfig() {
map('FEATURES_DEFAULT_AVATAR', 'path', 'features.default_avatar'), map('FEATURES_DEFAULT_AVATAR', 'path', 'features.default_avatar'),
map('FEATURES_ROBOTS_TXT', 'boolean', 'features.robots_txt'),
map('CHUNKS_MAX_SIZE', 'human-to-byte', 'chunks.max_size'), map('CHUNKS_MAX_SIZE', 'human-to-byte', 'chunks.max_size'),
map('CHUNKS_CHUNKS_SIZE', 'human-to-byte', 'chunks.chunks_size'), map('CHUNKS_CHUNKS_SIZE', 'human-to-byte', 'chunks.chunks_size'),
map('CHUNKS_ENABLED', 'boolean', 'chunks.enabled'), map('CHUNKS_ENABLED', 'boolean', 'chunks.enabled'),

View file

@ -4,7 +4,7 @@ import { inspect } from 'util';
import Logger from 'lib/logger'; import Logger from 'lib/logger';
import { humanToBytes } from 'utils/bytes'; import { humanToBytes } from 'utils/bytes';
import { tmpdir } from 'os'; import { tmpdir } from 'os';
import { join } from 'path'; import { join, resolve } from 'path';
const discord_content = s const discord_content = s
.object({ .object({
@ -53,7 +53,7 @@ const validator = s.object({
type: s.enum('local', 's3', 'supabase').default('local'), type: s.enum('local', 's3', 'supabase').default('local'),
local: s local: s
.object({ .object({
directory: s.string.default('./uploads'), directory: s.string.default(resolve('./uploads')).transform((v) => resolve(v)),
}) })
.default({ .default({
directory: './uploads', directory: './uploads',
@ -195,6 +195,7 @@ const validator = s.object({
user_registration: s.boolean.default(false), user_registration: s.boolean.default(false),
headless: s.boolean.default(false), headless: s.boolean.default(false),
default_avatar: s.string.nullable.default(null), default_avatar: s.string.nullable.default(null),
robots_txt: s.boolean.default(false),
}) })
.default({ .default({
invites: false, invites: false,
@ -204,6 +205,7 @@ const validator = s.object({
user_registration: false, user_registration: false,
headless: false, headless: false,
default_avatar: null, default_avatar: null,
robots_txt: false,
}), }),
chunks: s chunks: s
.object({ .object({

View file

@ -11,23 +11,23 @@ export class Local extends Datasource {
} }
public async save(file: string, data: Buffer): Promise<void> { public async save(file: string, data: Buffer): Promise<void> {
await writeFile(join(process.cwd(), this.path, file), data); await writeFile(join(this.path, file), data);
} }
public async delete(file: string): Promise<void> { public async delete(file: string): Promise<void> {
await rm(join(process.cwd(), this.path, file)); await rm(join(this.path, file));
} }
public async clear(): Promise<void> { public async clear(): Promise<void> {
const files = await readdir(join(process.cwd(), this.path)); const files = await readdir(this.path);
for (let i = 0; i !== files.length; ++i) { for (let i = 0; i !== files.length; ++i) {
await rm(join(process.cwd(), this.path, files[i])); await rm(join(this.path, files[i]));
} }
} }
public get(file: string): ReadStream { public get(file: string): ReadStream {
const full = join(process.cwd(), this.path, file); const full = join(this.path, file);
if (!existsSync(full)) return null; if (!existsSync(full)) return null;
try { try {
@ -38,7 +38,7 @@ export class Local extends Datasource {
} }
public async size(file: string): Promise<number> { public async size(file: string): Promise<number> {
const full = join(process.cwd(), this.path, file); const full = join(this.path, file);
if (!existsSync(full)) return 0; if (!existsSync(full)) return 0;
const stats = await stat(full); const stats = await stat(full);

View file

@ -168,7 +168,7 @@ export default function Login({
<Center sx={{ height: '100vh' }}> <Center sx={{ height: '100vh' }}>
<Card radius='md'> <Card radius='md'>
<Title size={30} align='left'> <Title size={30} align='left'>
{bypass_local_login ? ' Login to Zipline with' : 'Zipline'} {bypass_local_login ? ` Login to ${title} with` : title}
</Title> </Title>
{oauth_registration && ( {oauth_registration && (

View file

@ -100,6 +100,18 @@ async function start() {
return reply.type('image/x-icon').send(favicon); return reply.type('image/x-icon').send(favicon);
}); });
if (config.features.robots_txt) {
server.get('/robots.txt', async (_, reply) => {
return reply.type('text/plain').send(`User-Agent: *
Disallow: /r/
Disallow: /api/
Disallow: /view/
Disallow: ${config.uploader.route}
Disallow: ${config.urls.route}
`);
});
}
// makes sure to handle both in one route as you cant have two handlers with the same route // makes sure to handle both in one route as you cant have two handlers with the same route
if (config.urls.route === '/' && config.uploader.route === '/') { if (config.urls.route === '/' && config.uploader.route === '/') {
server.route({ server.route({

View file

@ -84,7 +84,6 @@ async function start() {
if (config.datasource.type === 'local') { if (config.datasource.type === 'local') {
fd = await open( fd = await open(
join( join(
process.cwd(),
config.datasource.local.directory, config.datasource.local.directory,
`${fileName}${compressionUsed ? '.jpg' : `${ext ? '.' : ''}${ext}`}` `${fileName}${compressionUsed ? '.jpg' : `${ext ? '.' : ''}${ext}`}`
), ),