mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-15 00:56:26 +08:00
c8cdc488db
#### PR Dependency Tree * **PR #14964** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added entitlement resolution to validate licenses and derive plan, quotas, expiry and flags. * Introduced persistent quota/entitlement state for users and workspaces with legacy sync behavior. * Real-time quota-state operations and change events for monitoring usage. * **Chores** * Updated workspace dependencies to add cryptography/hash crates. * **Tests** * Added native entitlement tests covering validation, quantity handling, and signature/expiry cases. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14964) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import test from 'ava';
|
|
|
|
import { resolveEntitlementV1 } from '../native';
|
|
|
|
test('native entitlement wrapper maps schema errors to invalid argument', t => {
|
|
const error = t.throws(() =>
|
|
resolveEntitlementV1({
|
|
deploymentType: 'local',
|
|
targetType: 'workspace',
|
|
now: '2026-05-14T00:00:00Z',
|
|
})
|
|
);
|
|
|
|
t.is((error as Error & { code?: string })?.code, 'InvalidArg');
|
|
});
|
|
|
|
test('native entitlement wrapper maps unsafe JS quantity to invalid argument', t => {
|
|
const base = {
|
|
deploymentType: 'cloud',
|
|
targetType: 'workspace',
|
|
plan: 'team',
|
|
now: '2026-05-14T00:00:00Z',
|
|
} as const;
|
|
|
|
for (const quantity of [4294967297, 1.5, 100001]) {
|
|
const error = t.throws(() => resolveEntitlementV1({ ...base, quantity }));
|
|
|
|
t.is(
|
|
(error as Error & { code?: string })?.code,
|
|
'InvalidArg',
|
|
String(quantity)
|
|
);
|
|
}
|
|
});
|
|
|
|
test('native entitlement wrapper does not trust forged signed payload buffers', t => {
|
|
const resolved = resolveEntitlementV1({
|
|
deploymentType: 'selfhosted',
|
|
targetType: 'workspace',
|
|
targetId: 'workspace-id',
|
|
signedPayload: Buffer.from('not-a-valid-license'),
|
|
publicKey: 'not-a-valid-public-key',
|
|
licenseAesKey: 'not-a-valid-aes-key',
|
|
now: '2026-05-14T00:00:00Z',
|
|
});
|
|
|
|
t.false(resolved.valid);
|
|
t.is(resolved.status, 'needs_reupload');
|
|
t.is(resolved.plan, 'selfhost_free');
|
|
});
|