mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
fix(server): cannot revalidate licenses (#9982)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
||||
import { Cron, CronExpression } from '@nestjs/schedule';
|
||||
import { InstalledLicense, PrismaClient } from '@prisma/client';
|
||||
|
||||
@@ -23,7 +23,7 @@ interface License {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class LicenseService {
|
||||
export class LicenseService implements OnModuleInit {
|
||||
private readonly logger = new Logger(LicenseService.name);
|
||||
|
||||
constructor(
|
||||
@@ -34,6 +34,55 @@ export class LicenseService {
|
||||
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 ({
|
||||
workspaceId,
|
||||
plan,
|
||||
recurring,
|
||||
quantity,
|
||||
}: Events['workspace.subscription.activated']) => {
|
||||
switch (plan) {
|
||||
case SubscriptionPlan.SelfHostedTeam:
|
||||
await this.models.workspaceFeature.add(
|
||||
workspaceId,
|
||||
'team_plan_v1',
|
||||
`${recurring} team subscription activated`,
|
||||
{
|
||||
memberLimit: quantity,
|
||||
}
|
||||
);
|
||||
await this.permission.refreshSeatStatus(workspaceId, quantity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private readonly onWorkspaceSubscriptionCanceled = async ({
|
||||
workspaceId,
|
||||
plan,
|
||||
}: Events['workspace.subscription.canceled']) => {
|
||||
switch (plan) {
|
||||
case SubscriptionPlan.SelfHostedTeam:
|
||||
await this.models.workspaceFeature.remove(workspaceId, 'team_plan_v1');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
async getLicense(workspaceId: string) {
|
||||
return this.db.installedLicense.findUnique({
|
||||
select: {
|
||||
@@ -208,10 +257,14 @@ export class LicenseService {
|
||||
|
||||
@Cron(CronExpression.EVERY_10_MINUTES)
|
||||
async licensesHealthCheck() {
|
||||
if (!this.config.isSelfhosted) {
|
||||
return;
|
||||
}
|
||||
|
||||
const licenses = await this.db.installedLicense.findMany({
|
||||
where: {
|
||||
validatedAt: {
|
||||
lte: new Date(Date.now() - 1000 * 60 * 60),
|
||||
lte: new Date(Date.now() - 1000 * 60 * 60 /* 1h */),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -224,7 +277,12 @@ export class LicenseService {
|
||||
private async revalidateLicense(license: InstalledLicense) {
|
||||
try {
|
||||
const res = await this.fetch<License>(
|
||||
`/api/team/licenses/${license.key}/health`
|
||||
`/api/team/licenses/${license.key}/health`,
|
||||
{
|
||||
headers: {
|
||||
'x-validate-key': license.validateKey,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
await this.db.installedLicense.update({
|
||||
@@ -272,18 +330,23 @@ export class LicenseService {
|
||||
init?: RequestInit
|
||||
): Promise<T & { res: Response }> {
|
||||
try {
|
||||
const res = await fetch('https://app.affine.pro' + path, {
|
||||
...init,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const res = await fetch(
|
||||
process.env.AFFINE_PRO_SERVER_ENDPOINT ??
|
||||
'https://app.affine.pro' + path,
|
||||
{
|
||||
...init,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...init?.headers,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
const body = (await res.json()) as UserFriendlyError;
|
||||
throw new UserFriendlyError(
|
||||
body.type as any,
|
||||
body.name as any,
|
||||
body.name.toLowerCase() as any,
|
||||
body.message,
|
||||
body.data
|
||||
);
|
||||
@@ -306,42 +369,4 @@ export class LicenseService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@OnEvent('workspace.subscription.activated')
|
||||
async onWorkspaceSubscriptionUpdated({
|
||||
workspaceId,
|
||||
plan,
|
||||
recurring,
|
||||
quantity,
|
||||
}: Events['workspace.subscription.activated']) {
|
||||
switch (plan) {
|
||||
case SubscriptionPlan.SelfHostedTeam:
|
||||
await this.models.workspaceFeature.add(
|
||||
workspaceId,
|
||||
'team_plan_v1',
|
||||
`${recurring} team subscription activated`,
|
||||
{
|
||||
memberLimit: quantity,
|
||||
}
|
||||
);
|
||||
await this.permission.refreshSeatStatus(workspaceId, quantity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@OnEvent('workspace.subscription.canceled')
|
||||
async onWorkspaceSubscriptionCanceled({
|
||||
workspaceId,
|
||||
plan,
|
||||
}: Events['workspace.subscription.canceled']) {
|
||||
switch (plan) {
|
||||
case SubscriptionPlan.SelfHostedTeam:
|
||||
await this.models.workspaceFeature.remove(workspaceId, 'team_plan_v1');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,21 +215,21 @@ export const DEFAULT_PRICES = new Map([
|
||||
// team
|
||||
[
|
||||
`${SubscriptionPlan.Team}_${SubscriptionRecurring.Monthly}`,
|
||||
{ product: 'AFFiNE Team(per seat)', price: 1500 },
|
||||
{ product: 'AFFiNE Team(per seat)', price: 1440 },
|
||||
],
|
||||
[
|
||||
`${SubscriptionPlan.Team}_${SubscriptionRecurring.Yearly}`,
|
||||
{ product: 'AFFiNE Team(per seat)', price: 14400 },
|
||||
{ product: 'AFFiNE Team(per seat)', price: 12000 },
|
||||
],
|
||||
|
||||
// selfhost team
|
||||
[
|
||||
`${SubscriptionPlan.SelfHostedTeam}_${SubscriptionRecurring.Monthly}`,
|
||||
{ product: 'AFFiNE Self-hosted Team(per seat)', price: 1500 },
|
||||
{ product: 'AFFiNE Self-hosted Team(per seat)', price: 1440 },
|
||||
],
|
||||
[
|
||||
`${SubscriptionPlan.SelfHostedTeam}_${SubscriptionRecurring.Yearly}`,
|
||||
{ product: 'AFFiNE Self-hosted Team(per seat)', price: 14400 },
|
||||
{ product: 'AFFiNE Self-hosted Team(per seat)', price: 12000 },
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user