feat(server): support installable license (#12181)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for installing self-hosted team licenses via encrypted license files.
  - Introduced a new "Onetime" license variant for self-hosted environments.
  - Added a GraphQL mutation to upload and install license files.
  - License details now display the license variant.

- **Bug Fixes**
  - Improved error messages for license activation and expiration, including dynamic reasons.

- **Localization**
  - Updated and improved license-related error messages for better clarity.

- **Tests**
  - Added comprehensive end-to-end tests for license installation scenarios.

- **Chores**
  - Enhanced environment variable handling and public key management for license verification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
forehalo
2025-05-09 04:16:05 +00:00
parent 3db91bdc8e
commit 93e01b4442
34 changed files with 718 additions and 187 deletions
+5 -1
View File
@@ -1,4 +1,5 @@
import { resolve } from 'node:path';
import { homedir } from 'node:os';
import { join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import pkg from '../package.json' with { type: 'json' };
@@ -9,6 +10,8 @@ declare global {
var env: Readonly<Env>;
// oxlint-disable-next-line no-var
var readEnv: <T>(key: string, defaultValue: T, availableValues?: T[]) => T;
// oxlint-disable-next-line no-var
var CUSTOM_CONFIG_PATH: string;
}
}
@@ -50,6 +53,7 @@ export type AppEnv = {
version: string;
};
globalThis.CUSTOM_CONFIG_PATH = join(homedir(), '.affine/config');
globalThis.readEnv = function readEnv<T>(
env: string,
defaultValue: T,