168 lines
4.3 KiB
TypeScript
168 lines
4.3 KiB
TypeScript
import {
|
|
BadRequestException,
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
Get,
|
|
Param,
|
|
Post,
|
|
Redirect,
|
|
Render,
|
|
Req,
|
|
Res,
|
|
Session,
|
|
UnauthorizedException,
|
|
UploadedFile,
|
|
UseInterceptors,
|
|
} from '@nestjs/common';
|
|
import { FileInterceptor } from '@nestjs/platform-express';
|
|
import { Request, Response } from 'express';
|
|
import { SessionData } from 'express-session';
|
|
import { unlink } from 'fs/promises';
|
|
import { OAuth2ClientService } from 'src/modules/objects/oauth2-client/oauth2-client.service';
|
|
import { UploadService } from 'src/modules/objects/upload/upload.service';
|
|
import { UserService } from 'src/modules/objects/user/user.service';
|
|
import { FormUtilityService } from 'src/modules/utility/services/form-utility.service';
|
|
import { SettingsService } from './settings.service';
|
|
|
|
@Controller('/account')
|
|
export class SettingsController {
|
|
constructor(
|
|
private readonly _service: SettingsService,
|
|
private readonly _form: FormUtilityService,
|
|
private readonly _upload: UploadService,
|
|
private readonly _user: UserService,
|
|
private readonly _client: OAuth2ClientService,
|
|
) {}
|
|
|
|
@Get()
|
|
@Redirect('/account/general')
|
|
public redirectGeneral() {
|
|
return;
|
|
}
|
|
|
|
@Get('general')
|
|
@Render('settings/general')
|
|
public general(@Req() req: Request) {
|
|
return this._form.populateTemplate(req, { user: req.user });
|
|
}
|
|
|
|
@Post('general')
|
|
public async updateDisplayName(
|
|
@Req() req: Request,
|
|
@Res() res: Response,
|
|
@Body() body: { display_name?: string },
|
|
) {
|
|
try {
|
|
const { display_name } = body;
|
|
if (!display_name) {
|
|
throw new Error('Display name is required.');
|
|
}
|
|
|
|
if (display_name.length < 3 || display_name.length > 32) {
|
|
throw new Error(
|
|
'Display name must be between 3 and 32 characters long.',
|
|
);
|
|
}
|
|
|
|
req.user.display_name = display_name;
|
|
|
|
await this._user.updateUser(req.user);
|
|
req.flash('message', {
|
|
error: false,
|
|
text: 'Display name has been changed!',
|
|
});
|
|
} catch (e: any) {
|
|
req.flash('message', {
|
|
error: true,
|
|
text: e.message,
|
|
});
|
|
}
|
|
res.redirect('/account/general');
|
|
}
|
|
|
|
@Post('avatar')
|
|
@UseInterceptors(FileInterceptor('file'))
|
|
async uploadAvatarFile(
|
|
@Req() req: Request,
|
|
@UploadedFile() file: Express.Multer.File,
|
|
) {
|
|
if (req.body.csrf !== req.session.csrf) {
|
|
throw new BadRequestException('Invalid session. Please try again.');
|
|
}
|
|
|
|
if (!file) {
|
|
throw new BadRequestException('Avatar upload failed');
|
|
}
|
|
|
|
try {
|
|
const matches = await this._upload.checkImageAspect(file);
|
|
if (!matches) {
|
|
throw new BadRequestException(
|
|
'Avatar should be with a 1:1 aspect ratio.',
|
|
);
|
|
}
|
|
} catch (e) {
|
|
await unlink(file.path);
|
|
throw e;
|
|
}
|
|
|
|
const upload = await this._upload.registerUploadedFile(file, req.user);
|
|
await this._user.updateAvatar(req.user, upload);
|
|
return {
|
|
file: upload.file,
|
|
};
|
|
}
|
|
|
|
@Post('avatar/delete')
|
|
public async deleteUserAvatar(@Req() req: Request, @Res() res: Response) {
|
|
this._user.deleteAvatar(req.user);
|
|
req.flash('message', {
|
|
error: false,
|
|
text: 'Avatar removed successfully.',
|
|
});
|
|
res.redirect('/account/general');
|
|
}
|
|
|
|
@Get('oauth2')
|
|
@Render('settings/oauth2')
|
|
public async authorizations(@Req() req: Request) {
|
|
const authorizations = await this._client.getAuthorizations(req.user);
|
|
return this._form.populateTemplate(req, { authorizations });
|
|
}
|
|
|
|
@Post('oauth2/revoke/:id')
|
|
public async revokeAuthorization(
|
|
@Req() req: Request,
|
|
@Res() res: Response,
|
|
@Param('id') id: number,
|
|
) {
|
|
const getAuth = await this._client.getAuthorization(req.user, id);
|
|
const jsreq =
|
|
req.header('content-type').startsWith('application/json') ||
|
|
req.header('accept').startsWith('application/json');
|
|
|
|
if (!getAuth) {
|
|
if (jsreq) {
|
|
throw new UnauthorizedException(
|
|
'Unauthorized or invalid revokation request',
|
|
);
|
|
}
|
|
|
|
req.flash('message', {
|
|
error: true,
|
|
text: 'Unauthorized revokation.',
|
|
});
|
|
res.redirect('/account/oauth2');
|
|
return;
|
|
}
|
|
|
|
await this._client.revokeAuthorization(getAuth);
|
|
|
|
if (jsreq) {
|
|
return res.json({ success: true });
|
|
}
|
|
res.redirect('/account/oauth2');
|
|
}
|
|
}
|