privilege

This commit is contained in:
Evert Prants 2022-04-15 22:00:02 +03:00
parent 8cff63a0a7
commit 3f399320b6
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
15 changed files with 129 additions and 10 deletions

View File

@ -9,6 +9,8 @@ dotenv.config();
const CONFIG_ENV = process.env.NODE_ENV === 'production' ? 'prod' : 'dev';
const CONFIG_FILENAME = process.env.CONFIG || `config.${CONFIG_ENV}.toml`;
const CONFIG_PATH = join(process.cwd(), CONFIG_FILENAME);
const config = toml.parse(readFileSync(CONFIG_PATH, { encoding: 'utf-8' }));
const config = JSON.parse(
JSON.stringify(toml.parse(readFileSync(CONFIG_PATH, { encoding: 'utf-8' }))),
);
module.exports = config.database;

View File

@ -21,6 +21,7 @@ import { DatabaseModule } from './modules/objects/database/database.module';
import { EmailModule } from './modules/objects/email/email.module';
import { OAuth2ClientModule } from './modules/objects/oauth2-client/oauth2-client.module';
import { OAuth2TokenModule } from './modules/objects/oauth2-token/oauth2-token.module';
import { PrivilegeModule } from './modules/objects/privilege/privilege.module';
import { UploadModule } from './modules/objects/upload/upload.module';
import { UserModule } from './modules/objects/user/user.module';
import { UtilityModule } from './modules/utility/utility.module';
@ -48,6 +49,7 @@ import { UtilityModule } from './modules/utility/utility.module';
OAuth2Module,
TwoFactorModule,
SettingsModule,
PrivilegeModule,
],
controllers: [AppController],
providers: [AppService, CSRFMiddleware],

View File

@ -11,6 +11,7 @@
--main-background: #314550;
--main: #2e6b81;
--main-light: #519eb9;
--main-darkish: #006683;
--main-darker: #005b74;
--main-dark: #042b3a;

View File

@ -17,9 +17,15 @@
}
&__nav {
display: flex;
padding: 2rem 0rem;
background-color: var(--main-darker);
&-content {
display: flex;
flex-grow: 1;
}
ul {
display: flex;
flex-direction: column;
@ -43,13 +49,17 @@
&.active {
border-right-color: var(--main-light);
font-weight: bold;
background-color: var(--main-darkish);
}
&:focus {
outline: 4px solid var(--focus-outline);
}
}
&:last-child {
margin-top: auto;
}
}
}
}
@ -177,6 +187,7 @@
padding: 0;
background-color: var(--main-darker);
box-shadow: 0px 6px 62px -14px rgba(0, 0, 0, 0.45);
flex-direction: column;
& > .settings__nav-content {
display: block;

30
src/fe/ts/upload.ts Normal file
View File

@ -0,0 +1,30 @@
export class UploadInput {
private wrap: HTMLElement;
private inner: HTMLElement;
private hover = false;
constructor(public input: HTMLInputElement) {}
initialize(): void {
this.wrap = document.createElement('div');
this.wrap.classList.add('upload__wrapper');
this.inner = document.createElement('div');
this.inner.classList.add('upload');
this.wrap.appendChild(this.inner);
this.inner.addEventListener('dragenter', () => {
this.hover = true;
this.inner.classList.add('upload--hovered');
});
this.inner.addEventListener('dragleave', () => {
this.hover = false;
this.inner.classList.remove('upload--hovered');
});
this.inner.addEventListener('dragover', () => {});
this.input.parentElement.appendChild(this.wrap);
}
}

View File

@ -13,6 +13,7 @@ export class UserMiddleware implements NestMiddleware {
// TODO: check for bans
const userObj = await this.userService.getByUUID(req.session.user, [
'picture',
'privileges',
]);
if (userObj && userObj.activated) {
req.user = userObj;

View File

@ -67,7 +67,7 @@ export class OAuth2Controller {
const token = res.locals.accessToken as OAuth2AccessToken;
const user = await this._service.userService.getById(
token.user_id as number,
['picture'],
['picture', 'privileges'],
);
if (!user) {
@ -101,6 +101,13 @@ export class OAuth2Controller {
userData.image_file = user.picture.file;
}
if (
token.scope.includes('privileges') ||
(token.scope.includes('user:privileges') && user.privileges?.length)
) {
userData.privileges = user.privileges;
}
return userData;
}
}

View File

@ -7,11 +7,9 @@ import {
Render,
Req,
Res,
Session,
} from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
import { Request, Response } from 'express';
import { SessionData } from 'express-session';
import { UserService } from 'src/modules/objects/user/user.service';
import { FormUtilityService } from 'src/modules/utility/services/form-utility.service';
import { RegisterDto } from './register.interfaces';

View File

@ -0,0 +1,10 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Privilege {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'text', nullable: false })
name: string;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { privilegeProviders } from './privilege.providers';
import { PrivilegeService } from './privilege.service';
@Module({
imports: [DatabaseModule],
providers: [...privilegeProviders, PrivilegeService],
exports: [PrivilegeService],
})
export class PrivilegeModule {}

View File

@ -0,0 +1,10 @@
import { Connection } from 'typeorm';
import { Privilege } from './privilege.entity';
export const privilegeProviders = [
{
provide: 'PRIVILEGE_REPOSITORY',
useFactory: (connection: Connection) => connection.getRepository(Privilege),
inject: ['DATABASE_CONNECTION'],
},
];

View File

@ -0,0 +1,11 @@
import { Inject, Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Privilege } from './privilege.entity';
@Injectable()
export class PrivilegeService {
constructor(
@Inject('PRIVILEGE_REPOSITORY')
private privilegeRepository: Repository<Privilege>,
) {}
}

View File

@ -2,11 +2,13 @@ import {
Column,
CreateDateColumn,
Entity,
JoinTable,
ManyToMany,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { Privilege } from '../privilege/privilege.entity';
import { Upload } from '../upload/upload.entity';
@Entity()
@ -54,4 +56,8 @@ export class User {
onUpdate: 'CASCADE',
})
public picture: Upload;
@ManyToMany(() => Privilege)
@JoinTable()
public privileges: Privilege[];
}

View File

@ -1,13 +1,20 @@
import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { EmailModule } from '../email/email.module';
import { PrivilegeModule } from '../privilege/privilege.module';
import { UploadModule } from '../upload/upload.module';
import { UserTokenModule } from '../user-token/user-token.module';
import { userProviders } from './user.providers';
import { UserService } from './user.service';
@Module({
imports: [DatabaseModule, EmailModule, UserTokenModule, UploadModule],
imports: [
DatabaseModule,
EmailModule,
UserTokenModule,
UploadModule,
PrivilegeModule,
],
providers: [...userProviders, UserService],
exports: [UserService],
})

View File

@ -10,11 +10,23 @@ block body
.settings__nav-content
ul
li
a(href="/account/general", class=path === '/account/general' ? 'active' : '') General
a(
href="/account/general",
class=path === '/account/general' ? 'active' : ''
aria-selected=path === '/account/general' ? 'true' : 'false'
) General
li
a(href="/account/oauth2", class=path === '/account/oauth2' ? 'active' : '') Authorizations
a(
href="/account/oauth2",
class=path === '/account/oauth2' ? 'active' : ''
aria-selected=path === '/account/oauth2' ? 'true' : 'false'
) Authorizations
li
a(href="/account/security", class=path === '/account/security' ? 'active' : '') Security
a(
href="/account/security",
class=path === '/account/security' ? 'active' : ''
aria-selected=path === '/account/security' ? 'true' : 'false'
) Security
li
a(href="/account/logout?csrf=" + csrf) Log out
section.content.settings__content