refactor(server): config system (#11081)
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { OptionalModule } from '../../base';
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { PermissionModule } from '../../core/permission';
|
||||
import { QuotaModule } from '../../core/quota';
|
||||
import { LicenseResolver } from './resolver';
|
||||
import { LicenseService } from './service';
|
||||
|
||||
@OptionalModule({
|
||||
@Module({
|
||||
imports: [QuotaModule, PermissionModule],
|
||||
providers: [LicenseService, LicenseResolver],
|
||||
})
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Resolver,
|
||||
} from '@nestjs/graphql';
|
||||
|
||||
import { ActionForbidden, Config } from '../../base';
|
||||
import { UseNamedGuard } from '../../base';
|
||||
import { CurrentUser } from '../../core/auth';
|
||||
import { AccessController } from '../../core/permission';
|
||||
import { WorkspaceType } from '../../core/workspaces';
|
||||
@@ -34,10 +34,10 @@ export class License {
|
||||
expiredAt!: Date | null;
|
||||
}
|
||||
|
||||
@UseNamedGuard('selfhost')
|
||||
@Resolver(() => WorkspaceType)
|
||||
export class LicenseResolver {
|
||||
constructor(
|
||||
private readonly config: Config,
|
||||
private readonly service: LicenseService,
|
||||
private readonly ac: AccessController
|
||||
) {}
|
||||
@@ -51,13 +51,6 @@ export class LicenseResolver {
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Parent() workspace: WorkspaceType
|
||||
): Promise<License | null> {
|
||||
// NOTE(@forehalo):
|
||||
// we can't simply disable license resolver for non-selfhosted server
|
||||
// it will make the gql codegen messed up.
|
||||
if (!this.config.isSelfhosted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
await this.ac
|
||||
.user(user.id)
|
||||
.workspace(workspace.id)
|
||||
@@ -71,10 +64,6 @@ export class LicenseResolver {
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('license') license: string
|
||||
) {
|
||||
if (!this.config.isSelfhosted) {
|
||||
throw new ActionForbidden();
|
||||
}
|
||||
|
||||
await this.ac
|
||||
.user(user.id)
|
||||
.workspace(workspaceId)
|
||||
@@ -88,10 +77,6 @@ export class LicenseResolver {
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string
|
||||
) {
|
||||
if (!this.config.isSelfhosted) {
|
||||
throw new ActionForbidden();
|
||||
}
|
||||
|
||||
await this.ac
|
||||
.user(user.id)
|
||||
.workspace(workspaceId)
|
||||
@@ -105,10 +90,6 @@ export class LicenseResolver {
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string
|
||||
) {
|
||||
if (!this.config.isSelfhosted) {
|
||||
throw new ActionForbidden();
|
||||
}
|
||||
|
||||
await this.ac
|
||||
.user(user.id)
|
||||
.workspace(workspaceId)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { Cron, CronExpression } from '@nestjs/schedule';
|
||||
import { InstalledLicense, PrismaClient } from '@prisma/client';
|
||||
|
||||
import {
|
||||
Config,
|
||||
EventBus,
|
||||
InternalServerError,
|
||||
LicenseNotFound,
|
||||
@@ -22,35 +21,22 @@ interface License {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class LicenseService implements OnModuleInit {
|
||||
export class LicenseService {
|
||||
private readonly logger = new Logger(LicenseService.name);
|
||||
|
||||
constructor(
|
||||
private readonly config: Config,
|
||||
private readonly db: PrismaClient,
|
||||
private readonly event: EventBus,
|
||||
private readonly models: Models
|
||||
) {}
|
||||
|
||||
async onModuleInit() {
|
||||
if (this.config.isSelfhosted) {
|
||||
this.event.on(
|
||||
'workspace.subscription.activated',
|
||||
this.onWorkspaceSubscriptionUpdated
|
||||
);
|
||||
this.event.on(
|
||||
'workspace.subscription.canceled',
|
||||
this.onWorkspaceSubscriptionCanceled
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly onWorkspaceSubscriptionUpdated = async ({
|
||||
@OnEvent('workspace.subscription.activated')
|
||||
async onWorkspaceSubscriptionUpdated({
|
||||
workspaceId,
|
||||
plan,
|
||||
recurring,
|
||||
quantity,
|
||||
}: Events['workspace.subscription.activated']) => {
|
||||
}: Events['workspace.subscription.activated']) {
|
||||
switch (plan) {
|
||||
case SubscriptionPlan.SelfHostedTeam:
|
||||
await this.models.workspaceFeature.add(
|
||||
@@ -66,12 +52,13 @@ export class LicenseService implements OnModuleInit {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private readonly onWorkspaceSubscriptionCanceled = async ({
|
||||
@OnEvent('workspace.subscription.canceled')
|
||||
async onWorkspaceSubscriptionCanceled({
|
||||
workspaceId,
|
||||
plan,
|
||||
}: Events['workspace.subscription.canceled']) => {
|
||||
}: Events['workspace.subscription.canceled']) {
|
||||
switch (plan) {
|
||||
case SubscriptionPlan.SelfHostedTeam:
|
||||
await this.models.workspaceFeature.remove(workspaceId, 'team_plan_v1');
|
||||
@@ -79,7 +66,7 @@ export class LicenseService implements OnModuleInit {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async getLicense(workspaceId: string) {
|
||||
return this.db.installedLicense.findUnique({
|
||||
@@ -201,10 +188,6 @@ export class LicenseService implements OnModuleInit {
|
||||
|
||||
@OnEvent('workspace.members.updated')
|
||||
async updateTeamSeats(payload: Events['workspace.members.updated']) {
|
||||
if (!this.config.isSelfhosted) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { workspaceId, count } = payload;
|
||||
|
||||
const license = await this.db.installedLicense.findUnique({
|
||||
@@ -251,12 +234,8 @@ export class LicenseService implements OnModuleInit {
|
||||
throw new Error('Timeout checking seat update result.');
|
||||
}
|
||||
|
||||
@Cron(CronExpression.EVERY_10_MINUTES)
|
||||
@Cron(CronExpression.EVERY_10_MINUTES, { disabled: !env.selfhosted })
|
||||
async licensesHealthCheck() {
|
||||
if (!this.config.isSelfhosted) {
|
||||
return;
|
||||
}
|
||||
|
||||
const licenses = await this.db.installedLicense.findMany({
|
||||
where: {
|
||||
validatedAt: {
|
||||
|
||||
Reference in New Issue
Block a user