Skip to content

Commit 2bf8027

Browse files
authored
feat: billing (#672)
* feat: space supports displaying the plan level * chore: update icons and table component * feat: add the PAYMENT_REQUIRED http code * feat: admin user & setting config * feat: usage limit * feat: add paste checker for usage * chore: db migration * feat: user limit for license * feat: admin settings * refactor: use generics as the type for the custom ssrApi * fix: type error * fix: setting for disallow signup * refactor: obtain the settings from the database instead of from cls
1 parent 13b4463 commit 2bf8027

File tree

86 files changed

+1429
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1429
-118
lines changed

apps/nestjs-backend/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { NextModule } from './features/next/next.module';
1616
import { NotificationModule } from './features/notification/notification.module';
1717
import { PinModule } from './features/pin/pin.module';
1818
import { SelectionModule } from './features/selection/selection.module';
19+
import { SettingModule } from './features/setting/setting.module';
1920
import { ShareModule } from './features/share/share.module';
2021
import { SpaceModule } from './features/space/space.module';
2122
import { UserModule } from './features/user/user.module';
@@ -47,6 +48,7 @@ export const appModules = {
4748
ImportOpenApiModule,
4849
ExportOpenApiModule,
4950
PinModule,
51+
SettingModule,
5052
],
5153
providers: [InitBootstrapProvider],
5254
};

apps/nestjs-backend/src/configs/base.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ConfigType } from '@nestjs/config';
44
import { registerAs } from '@nestjs/config';
55

66
export const baseConfig = registerAs('base', () => ({
7+
isCloud: process.env.NEXT_BUILD_ENV_EDITION?.toUpperCase() === 'CLOUD',
78
brandName: process.env.BRAND_NAME!,
89
publicOrigin: process.env.PUBLIC_ORIGIN!,
910
storagePrefix: process.env.STORAGE_PREFIX ?? process.env.PUBLIC_ORIGIN!,

apps/nestjs-backend/src/custom.exception.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export const getDefaultCodeByStatus = (status: HttpStatus) => {
1616
return HttpErrorCode.VALIDATION_ERROR;
1717
case HttpStatus.UNAUTHORIZED:
1818
return HttpErrorCode.UNAUTHORIZED;
19+
case HttpStatus.PAYMENT_REQUIRED:
20+
return HttpErrorCode.PAYMENT_REQUIRED;
1921
case HttpStatus.FORBIDDEN:
2022
return HttpErrorCode.RESTRICTED_RESOURCE;
2123
case HttpStatus.NOT_FOUND:

apps/nestjs-backend/src/event-emitter/events/event.enum.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,7 @@ export enum Events {
4040
// USER_PASSWORD_RESET = 'user.password.reset',
4141
USER_PASSWORD_CHANGE = 'user.password.change',
4242
// USER_PASSWORD_FORGOT = 'user.password.forgot'
43+
44+
COLLABORATOR_CREATE = 'collaborator.create',
45+
COLLABORATOR_DELETE = 'collaborator.delete',
4346
}

apps/nestjs-backend/src/event-emitter/events/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export * from './core-event';
33
export * from './op-event';
44
export * from './base/base.event';
55
export * from './space/space.event';
6+
export * from './space/collaborator.event';
67
export * from './table';
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Events } from '../event.enum';
2+
3+
export class CollaboratorCreateEvent {
4+
public readonly name = Events.COLLABORATOR_CREATE;
5+
6+
constructor(public readonly spaceId: string) {}
7+
}
8+
9+
export class CollaboratorDeleteEvent {
10+
public readonly name = Events.COLLABORATOR_DELETE;
11+
12+
constructor(public readonly spaceId: string) {}
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Events } from '../event.enum';
2+
3+
export class UserSignUpEvent {
4+
public readonly name = Events.USER_SIGNUP;
5+
6+
constructor(public readonly userId: string) {}
7+
}

apps/nestjs-backend/src/features/auth/strategies/access-token.strategy.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export class AccessTokenStrategy extends PassportStrategy(PassportAccessTokenStr
3232
if (!user) {
3333
throw new UnauthorizedException();
3434
}
35+
if (user.deactivatedTime) {
36+
throw new UnauthorizedException('Your account has been deactivated by the administrator');
37+
}
3538

3639
this.cls.set('user.id', user.id);
3740
this.cls.set('user.name', user.name);

apps/nestjs-backend/src/features/auth/strategies/github.strategy.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, UnauthorizedException } from '@nestjs/common';
1+
import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common';
22
import { ConfigType } from '@nestjs/config';
33
import { PassportStrategy } from '@nestjs/passport';
44
import type { Profile } from 'passport-github2';
@@ -42,6 +42,9 @@ export class GithubStrategy extends PassportStrategy(Strategy, 'github') {
4242
if (!user) {
4343
throw new UnauthorizedException('Failed to create user from GitHub profile');
4444
}
45+
if (user.deactivatedTime) {
46+
throw new BadRequestException('Your account has been deactivated by the administrator');
47+
}
4548
await this.userService.refreshLastSignTime(user.id);
4649
return pickUserMe(user);
4750
}

apps/nestjs-backend/src/features/auth/strategies/google.strategy.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, UnauthorizedException } from '@nestjs/common';
1+
import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common';
22
import { ConfigType } from '@nestjs/config';
33
import { PassportStrategy } from '@nestjs/passport';
44
import type { Profile } from 'passport-google-oauth20';
@@ -44,6 +44,9 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
4444
if (!user) {
4545
throw new UnauthorizedException('Failed to create user from Google profile');
4646
}
47+
if (user.deactivatedTime) {
48+
throw new BadRequestException('Your account has been deactivated by the administrator');
49+
}
4750
await this.userService.refreshLastSignTime(user.id);
4851
return pickUserMe(user);
4952
}

0 commit comments

Comments
 (0)