Skip to content

Commit

Permalink
🚧 Store registration preference
Browse files Browse the repository at this point in the history
  • Loading branch information
moisout committed Dec 26, 2023
1 parent 101bcb3 commit 1e859b2
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 128 deletions.
35 changes: 30 additions & 5 deletions client/components/admin/UserManagement.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
<script setup lang="ts">
const disableRegistration = ref(false);
import { useMessagesStore } from '~/store/messages';
const { apiUrl } = useApiUrl();
const { vtFetch } = useVtFetch();
const messagesStore = useMessagesStore();
const { data, refresh } = useGetServerSettings();
const onRegistrationEnabledChange = async (value: boolean) => {
await vtFetch(`${apiUrl.value}admin/server-settings`, {
method: 'POST',
body: {
registrationEnabled: value
}
});
await refresh();
await nextTick();
messagesStore.createMessage({
type: 'info',
title: 'Server settings updated',
message: `Public registration ${value ? 'enabled' : 'disabled'}`
});
};
</script>

<template>
<div class="user-management">
<div v-if="data" class="user-management">
<ButtonsSwitchButton
label="Disable registration"
:value="disableRegistration"
small-label="Disables registration. Users can only be created by the admin."
label="Enable public registration"
:value="data.registrationEnabled"
small-label="Anyone can create an account."
small-label-negative="Accounts can only be created by the admin."
@valuechange="onRegistrationEnabledChange"
/>
</div>
<Spinner v-if="!data" />
</template>

<style lang="scss" scoped>
Expand Down
26 changes: 21 additions & 5 deletions client/components/buttons/SwitchButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@
</div>
<div v-if="label" class="label-container">
<label :for="`switch-button-${randomId}`" class="label">{{ label }}</label>
<label v-if="smallLabel" :for="`switch-button-${randomId}`" class="small-label">{{
smallLabel
}}</label>

<label
v-if="smallLabel && smallLabelNegative && !value"
:for="`switch-button-${randomId}`"
class="small-label"
>
{{ smallLabelNegative }}
</label>
<label v-else-if="smallLabel" :for="`switch-button-${randomId}`" class="small-label">
{{ smallLabel }}
</label>
</div>
</div>
</template>
Expand All @@ -33,7 +41,13 @@ export default defineComponent({
label: String,

Check warning on line 41 in client/components/buttons/SwitchButton.vue

View workflow job for this annotation

GitHub Actions / lint:client

Prop 'label' requires default value to be set
smallLabel: {
type: String,
required: false
required: false,
default: null
},
smallLabelNegative: {
type: String,
required: false,
default: null
},
disabled: Boolean,
right: {
Expand Down Expand Up @@ -176,7 +190,9 @@ export default defineComponent({
background-color: var(--theme-color);
display: block;
position: absolute;
transition: background-color 300ms $intro-easing, left 300ms $overshoot-easing;
transition:
background-color 300ms $intro-easing,
left 300ms $overshoot-easing;
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions client/composables/api/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ export const useGetAdminInfo = () => {
});
};

export const useGetServerSettings = () => {
const { apiUrl } = useApiUrl();
const { vtFetch } = useVtFetch();

return useLazyAsyncData(
'server-settings',
() => vtFetch<ApiDto<'ServerSettingsDto'>>(`${apiUrl.value}admin/server-settings`),
{
server: false
}
);
};

export const useGetBlockedVideos = () => {
const { apiUrl } = useApiUrl();

Expand Down
11 changes: 11 additions & 0 deletions server/src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Private } from 'server/auth/decorators/private.decorator';
import { InfoDto } from './dto/info.dto';
import { UserDto } from 'server/user/user.dto';
import { UserprofileDto } from 'server/user/dto/userprofile.dto';
import { ServerSettingsDto } from './dto/server-settings.dto';

@ApiTags('Admin')
@UseGuards(AdminGuard)
Expand All @@ -30,6 +31,16 @@ export class AdminController {
return this.adminService.getInfo();
}

@Get('server-settings')
getServerSettings(): Promise<ServerSettingsDto> {
return this.adminService.getServerSettings();
}

@Post('server-settings')
updateServerSettings(@Body() serverSettings: ServerSettingsDto): Promise<ServerSettingsDto> {
return this.adminService.updateServerSettings(serverSettings);
}

@Get('logs')
getLogs(): Promise<LogsDto> {
return this.adminService.getLogs();
Expand Down
6 changes: 6 additions & 0 deletions server/src/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AdminService } from './admin.service';
import { AdminController } from './admin.controller';
import { BlockedVideo, BlockedVideoSchema } from './schemas/blocked-video';
import { UserModule } from '../user/user.module';
import { ServerSettings, ServerSettingsSchema } from './schemas/server-settings';

const moduleMetadata: ModuleMetadata = {
imports: [
Expand All @@ -19,6 +20,11 @@ const moduleMetadata: ModuleMetadata = {
name: BlockedVideo.name,
schema: BlockedVideoSchema,
collection: 'blocked-videos'
},
{
name: ServerSettings.name,
schema: ServerSettingsSchema,
collection: 'server-settings'
}
]),
UserModule
Expand Down
43 changes: 38 additions & 5 deletions server/src/admin/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import { proxyEnabled } from 'server/common/proxyAgent';
import { UserprofileDto } from '../user/dto/userprofile.dto';
import { UserService } from '../user/user.service';
import { UserDto } from '../user/user.dto';
import { ServerSettingsDto } from './dto/server-settings.dto';
import { ServerSettings } from './schemas/server-settings';

@Injectable()
export class AdminService {
constructor(
private configService: ConfigService,
@InjectModel(BlockedVideo.name)
private readonly blockedVideoModel: Model<BlockedVideo>,
private readonly BlockedVideoModel: Model<BlockedVideo>,
@InjectModel(ServerSettings.name)
private readonly ServerSettingsModel: Model<ServerSettings>,
private userService: UserService
) {}

Expand Down Expand Up @@ -96,6 +100,35 @@ export class AdminService {
return createdUser;
}

defaultSettings: ServerSettingsDto = {
registrationEnabled: true
};

async getServerSettings(): Promise<ServerSettingsDto> {
const serverSettings = await this.ServerSettingsModel.findOne({ version: 1 }).exec();
if (!serverSettings) {
return this.defaultSettings;
}
return serverSettings;
}

async updateServerSettings(serverSettings: ServerSettingsDto): Promise<ServerSettingsDto> {
const settingsToSet: ServerSettingsDto = {
...this.defaultSettings,
...serverSettings
};

const newSettings = await this.ServerSettingsModel.findOneAndUpdate(
{ version: 1 },
{ version: 1, ...settingsToSet },
{
upsert: true
}
).exec();

return newSettings;
}

async dowloadLogFile(logFile: string): Promise<StreamableFile> {
let logFolder = resolve(__dirname, '../logs');
if (this.configService.get('VIEWTUBE_BASE_DIR')) {
Expand All @@ -117,12 +150,12 @@ export class AdminService {
}

async getAllBlockedVideoIds(): Promise<string[]> {
const blockedVideos = await this.blockedVideoModel.find().exec();
const blockedVideos = await this.BlockedVideoModel.find().exec();
return blockedVideos.map(video => video.videoId);
}

async isVideoBlocked(videoId: string): Promise<boolean> {
const blockedVideo = await this.blockedVideoModel.findOne({ videoId }).exec();
const blockedVideo = await this.BlockedVideoModel.findOne({ videoId }).exec();
if (!blockedVideo) {
return false;
}
Expand All @@ -134,7 +167,7 @@ export class AdminService {
if (!videoIdToBlock) {
throw new BadRequestException();
}
const blockedVideo = await this.blockedVideoModel.findOneAndUpdate(
const blockedVideo = await this.BlockedVideoModel.findOneAndUpdate(
{ videoId },
{ videoId },
{ new: true, upsert: true }
Expand All @@ -143,6 +176,6 @@ export class AdminService {
}

async unblockVideoId(videoId: string): Promise<void> {
await this.blockedVideoModel.findOneAndDelete({ videoId });
await this.BlockedVideoModel.findOneAndDelete({ videoId });
}
}
3 changes: 3 additions & 0 deletions server/src/admin/dto/server-settings.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class ServerSettingsDto {
registrationEnabled: boolean;
}
14 changes: 14 additions & 0 deletions server/src/admin/schemas/server-settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Document } from 'mongoose';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { ServerSettingsDto } from '../dto/server-settings.dto';

@Schema()
export class ServerSettings extends Document implements ServerSettingsDto {
@Prop()
version: number;

@Prop()
registrationEnabled: boolean;
}

export const ServerSettingsSchema = SchemaFactory.createForClass(ServerSettings);
Loading

0 comments on commit 1e859b2

Please sign in to comment.