Accounts with limits: a Newznab key and a tier per user, daily API and NZB counts, invites
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:
1 parent
c55918350e
commit
1322e42fb7
23 files changed
+1023
-39
No files matched your search
@@ -0,0 +1,37 @@
|
||||
import { BaseCommand, flags } from '@adonisjs/core/ace'
|
||||
import type { CommandOptions } from '@adonisjs/core/types/ace'
|
||||
import db from '@adonisjs/lucid/services/db'
|
||||
import AccessService from '#services/access_service'
|
||||
import { TIERS } from '#config/access'
|
||||
|
||||
/** Makes invite codes (SIGNUP=invite), optionally with a tier for the new account, e.g. a sold VIP year. */
|
||||
export default class AccessInvite extends BaseCommand {
|
||||
static commandName = 'access:invite'
|
||||
static description = 'Makes invite codes, optionally giving a tier (e.g. --tier=vip --days=365)'
|
||||
static options: CommandOptions = { startApp: true }
|
||||
|
||||
@flags.number({ description: 'How many codes', default: 1 })
|
||||
declare count: number
|
||||
|
||||
@flags.string({ description: `Tier the new account gets (${Object.keys(TIERS).join(', ')})` })
|
||||
declare tier?: string
|
||||
|
||||
@flags.number({ description: 'For how many days the tier holds (without: no end)' })
|
||||
declare days?: number
|
||||
|
||||
@flags.string({ description: 'A note, e.g. who it is for or the payment' })
|
||||
declare note?: string
|
||||
|
||||
async run() {
|
||||
if (this.tier && !TIERS[this.tier]) {
|
||||
this.logger.error(`No such tier: ${this.tier}`)
|
||||
this.exitCode = 1
|
||||
return
|
||||
}
|
||||
const codes = Array.from({ length: this.count }, () => AccessService.newKey())
|
||||
await db.table('invites').multiInsert(
|
||||
codes.map((code) => ({ code, tier: this.tier ?? null, tier_days: this.tier ? (this.days ?? null) : null, note: this.note ?? null }))
|
||||
)
|
||||
for (const code of codes) this.logger.log(code)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user