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>
27 lines
1.0 KiB
TypeScript
27 lines
1.0 KiB
TypeScript
import { randomBytes } from 'node:crypto'
|
|
import { UserSchema } from '#database/schema'
|
|
import { beforeCreate } from '@adonisjs/lucid/orm'
|
|
import hash from '@adonisjs/core/services/hash'
|
|
import { compose } from '@adonisjs/core/helpers'
|
|
import { withAuthFinder } from '@adonisjs/auth/mixins/lucid'
|
|
import { type AccessToken, DbAccessTokensProvider } from '@adonisjs/auth/access_tokens'
|
|
|
|
export default class User extends compose(UserSchema, withAuthFinder(hash)) {
|
|
static accessTokens = DbAccessTokensProvider.forModel(User)
|
|
declare currentAccessToken?: AccessToken
|
|
|
|
/** The Newznab key (AccessService), known on the model right away rather than from the column's default. */
|
|
@beforeCreate()
|
|
static assignApiKey(user: User) {
|
|
user.apiKey ??= randomBytes(16).toString('hex')
|
|
}
|
|
|
|
get initials() {
|
|
const [first, last] = this.fullName ? this.fullName.split(' ') : this.email.split('@')
|
|
if (first && last) {
|
|
return `${first.charAt(0)}${last.charAt(0)}`.toUpperCase()
|
|
}
|
|
return `${first.slice(0, 2)}`.toUpperCase()
|
|
}
|
|
}
|