privilege
This commit is contained in:
parent
8cff63a0a7
commit
3f399320b6
@ -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;
|
@ -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],
|
||||
|
@ -11,6 +11,7 @@
|
||||
--main-background: #314550;
|
||||
--main: #2e6b81;
|
||||
--main-light: #519eb9;
|
||||
--main-darkish: #006683;
|
||||
--main-darker: #005b74;
|
||||
--main-dark: #042b3a;
|
||||
|
||||
|
@ -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
30
src/fe/ts/upload.ts
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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';
|
||||
|
10
src/modules/objects/privilege/privilege.entity.ts
Normal file
10
src/modules/objects/privilege/privilege.entity.ts
Normal 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;
|
||||
}
|
11
src/modules/objects/privilege/privilege.module.ts
Normal file
11
src/modules/objects/privilege/privilege.module.ts
Normal 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 {}
|
10
src/modules/objects/privilege/privilege.providers.ts
Normal file
10
src/modules/objects/privilege/privilege.providers.ts
Normal 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'],
|
||||
},
|
||||
];
|
11
src/modules/objects/privilege/privilege.service.ts
Normal file
11
src/modules/objects/privilege/privilege.service.ts
Normal 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>,
|
||||
) {}
|
||||
}
|
@ -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[];
|
||||
}
|
||||
|
@ -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],
|
||||
})
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user