Accounts with limits: a Newznab key and a tier per user, daily API and NZB counts, invites
Test and deploy / test (push) Successful in 47s
Test and deploy / edge (push) Successful in 1m44s
Test and deploy / deploy (push) Skipped

ACCESS=accounts (config/access.ts; open stays the default and behaves as
before): Newznab and the catalog's releases routes name a user (apikey or
the web interface's token), whose tier sets searches and NZBs per UTC day
(Newznab 500/501, the catalog 429) and how far back they see (102/403).
Counted in one upsert per use, so the last one can't be taken twice;
caps, stats and refused requests aren't counted. Signup takes an invite
(SIGNUP), which may give a tier; ace access:invite, access:tier (extends a
running tier), access:suspend. The web interface signs in and shows the
day's usage and the Newznab key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Opus 5.5 committed 2026-10-17 00:16:45 +02:00
1 parent c55918350e
commit 1322e42fb7
23 files changed
+1023 -39

No files matched your search

+41 -1
View File
@@ -87,6 +87,25 @@ export class GroupSchema extends BaseModel {
declare tail: boolean
}
export class InviteSchema extends BaseModel {
static $columns = ['code', 'createdAt', 'note', 'tier', 'tierDays', 'usedAt', 'usedBy'] as const
$columns = InviteSchema.$columns
@column({ isPrimary: true })
declare code: string
@column.dateTime({ autoCreate: true })
declare createdAt: DateTime
@column()
declare note: string | null
@column()
declare tier: string | null
@column()
declare tierDays: number | null
@column.dateTime()
declare usedAt: DateTime | null
@column()
declare usedBy: number | null
}
export class NodeAccessTokenSchema extends BaseModel {
static $columns = ['abilities', 'createdAt', 'expiresAt', 'hash', 'id', 'lastUsedAt', 'name', 'tokenableId', 'type', 'updatedAt'] as const
$columns = NodeAccessTokenSchema.$columns
@@ -399,9 +418,24 @@ export class RuleSetSchema extends BaseModel {
declare version: number
}
export class UsageSchema extends BaseModel {
static $columns = ['apiHits', 'day', 'grabs', 'userId'] as const
$columns = UsageSchema.$columns
@column()
declare apiHits: number
@column.date()
declare day: DateTime
@column()
declare grabs: number
@column({ isPrimary: true })
declare userId: number
}
export class UserSchema extends BaseModel {
static $columns = ['createdAt', 'email', 'fullName', 'id', 'password', 'updatedAt'] as const
static $columns = ['apiKey', 'createdAt', 'email', 'fullName', 'id', 'password', 'suspended', 'tier', 'tierUntil', 'updatedAt'] as const
$columns = UserSchema.$columns
@column()
declare apiKey: string
@column.dateTime({ autoCreate: true })
declare createdAt: DateTime
@column()
@@ -412,6 +446,12 @@ export class UserSchema extends BaseModel {
declare id: number
@column({ serializeAs: null })
declare password: string
@column()
declare suspended: boolean
@column()
declare tier: string
@column.dateTime()
declare tierUntil: DateTime | null
@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updatedAt: DateTime | null
}