import { TTLCache, TTLCacheOptions } from "@isaacs/ttlcache"; import { Client, Client as RedisClient, ClientOptions as RedisClientOptions, JsonAdapter, JsonAdapter as RedisJsonAdapter, Watcher as RedisWatcher, buildKeyPath as buildRedisKeyPath, escapeKey as escapeRedisKey, parseKeyPath as parseRedisKeyPath } from "redis-extension"; import { IPermissionEvaluator } from "@authup/access"; import { ObjectLiteral } from "@authup/kit"; import { JWKType, JWTAlgorithm, JWTClaims, JWTHeader, OAuth2TokenPayload } from "@authup/specs"; import { EventPayload } from "@authup/core-realtime-kit"; import { Emitter } from "@socket.io/redis-emitter"; import { Identity } from "@authup/core-kit"; import { IQuery } from "@rapiq/core"; //#region src/cache/types.d.ts export type CacheKeyBuildOptions = { key: string; prefix?: string; suffix?: string; }; export type CacheSetOptions = { /** * Time to live in milliseconds (ms). */ ttl?: number; }; export type CacheClearOptions = { prefix?: string; suffix?: string; }; export interface ICache { set(key: string, value: any, options?: CacheSetOptions): Promise; /** * Atomically set the value ONLY if the key does not already exist * (set-if-absent). Returns true when the value was stored, false when the * key was already present. The building block for a distributed lock — * atomic on Redis (`SET … NX`) and on the in-process memory adapter. */ add(key: string, value: any, options?: CacheSetOptions): Promise; /** * Atomically refresh the TTL only when the stored value still matches the * supplied scalar owner token. Used to renew a distributed lock without * extending a successor's lease after ownership changed. */ renewIfValue(key: string, value: string, ttl: number): Promise; /** * Atomically delete a key only when its value still matches the supplied * scalar owner token. Used to release a distributed lock owner-safely. */ dropIfValue(key: string, value: string): Promise; /** * Atomically increment the numeric value stored at the key by `value` * (default 1), treating an absent key as 0, and return the * post-increment value. A ttl (re)arms the key's expiry on every call — * the building block for a sliding-window counter (attempt throttling). * Concurrent increments never lose an update — atomic on Redis * (`INCRBY`) and on the in-process memory adapter. Rejects when the key * holds a non-numeric value. */ increment(key: string, value?: number, options?: CacheSetOptions): Promise; has(key: string): Promise; get(key: string): Promise; pop(key: string): Promise; drop(key: string): Promise; dropMany(keys: string[]): Promise; clear(options?: CacheClearOptions): Promise; } //#endregion //#region src/cache/adapters/memory.d.ts export declare class MemoryCache implements ICache { protected instance: TTLCache; constructor(options?: TTLCacheOptions); pop(key: string): Promise; has(key: string): Promise; get(key: string): Promise; set(key: string, value: unknown, options: CacheSetOptions): Promise; add(key: string, value: unknown, options?: CacheSetOptions): Promise; renewIfValue(key: string, value: string, ttl: number): Promise; dropIfValue(key: string, value: string): Promise; increment(key: string, value?: number, options?: CacheSetOptions): Promise; drop(key: string): Promise; dropMany(keys: string[]): Promise; clear(options?: CacheClearOptions): Promise; } //#endregion //#region src/redis/factory.d.ts export type RedisClientCreateInput = string | boolean | RedisClient | RedisClientOptions; export declare function createRedisClient(input: RedisClientCreateInput): RedisClient; //#endregion //#region src/redis/check.d.ts export declare function isRedisClient(data: unknown): data is RedisClient; //#endregion //#region src/cache/adapters/redis.d.ts export declare class RedisCache implements ICache { protected client: Client; protected jsonAdapter: JsonAdapter; constructor(input: string | boolean | RedisClient | RedisClientOptions); get(key: string): Promise; pop(key: string): Promise; has(key: string): Promise; set(key: string, value: any, options: CacheSetOptions): Promise; add(key: string, value: any, options?: CacheSetOptions): Promise; renewIfValue(key: string, value: string, ttl: number): Promise; dropIfValue(key: string, value: string): Promise; increment(key: string, value?: number, options?: CacheSetOptions): Promise; drop(key: string): Promise; dropMany(keys: string[]): Promise; clear(options?: CacheClearOptions): Promise; } //#endregion //#region src/cache/helper.d.ts export declare function buildCacheKey(options: CacheKeyBuildOptions): string; //#endregion //#region src/core/actor/types.d.ts export type ActorContext = { permissionEvaluator: IPermissionEvaluator; identity?: Identity; }; //#endregion //#region src/core/service.d.ts export declare abstract class AbstractEntityService { protected getActorRealmId(actor: ActorContext): string | undefined; /** * Resource-realm entry for a permission `evaluate()` input, spread into the PolicyData * literal: `new PolicyData({ [ATTRIBUTES]: x, ...this.resourceRealmMatch(x) })`. It mirrors * ATTRIBUTES `realmId` PRESENCE — the `realmMatch` key is set only when the source carries * `realmId`, so a self-edit UPDATE (where the validator strips `realmId`) leaves the key * ABSENT and the realm_scope reach factor neutral-passes, exactly as the pre-key behavior. * A present `realmId: null` (global resource) is carried as `null` (and `own` denies it). */ protected resourceRealmMatch(source: Record): Record; } //#endregion //#region src/core/junction-service.d.ts /** * Base class for junction/association entity services (role-permission, user-role, * client-scope, …) whose rows carry no top-level `realmId`, only the realm of the * entities they link. The OWNER entity's realm gates a junction write — it is supplied to * the realm_scope reach factor under the `realmMatch` PolicyData key (RealmMatchPolicyEvaluator * SCOPE MODE), NOT stamped into ATTRIBUTES — so junction ATTRIBUTES carry only genuine * columns and an ATTRIBUTE_NAMES policy never mis-sees a synthetic `realmId`. */ export declare abstract class JunctionEntityService extends AbstractEntityService { /** * Attribute carrying the OWNER entity's realm — the realm-bound entity whose * sub-resource this junction manages (e.g. `roleRealmId` for role-permission, * `userRealmId` for user-role). `abstract` => every junction service MUST declare * it; a missing declaration is a compile error, which is what closes the fail-open * gap (a structural guard, not a convention). */ protected abstract readonly ownerRealmKey: string; /** * The junction's genuine attributes for a permission `evaluate()` — a COPY of the row * (never the persisted entity). No synthetic `realmId`; the owner realm travels * separately via {@link junctionResourceRealm}. */ protected junctionAttributes(entity: Record): Record; /** * The OWNER realm for the realm_scope reach factor — set under the `realmMatch` PolicyData * key alongside ATTRIBUTES. A `null` owner (global) is matched (and `own` correctly denies * it). Reading `ownerRealmKey` keeps the compile-time guard: a junction cannot silently * skip its realm. */ protected junctionResourceRealm(entity: Record): string | null; } //#endregion //#region src/core/types.d.ts /** * The pagination actually applied to a list query — mirrors the * pagination block a rapiq adapter reports back (limit/offset). */ export type EntityRepositoryPaginationMeta = { limit?: number; offset?: number; }; export type EntityRepositoryFindManyResult = { data: T[]; meta: EntityRepositoryPaginationMeta & { total: number; }; }; export interface IEntityRepository { findMany(query: IQuery): Promise>; findOneById(id: string): Promise; findOneByName(name: string, realm?: string): Promise; findOneByIdOrName(idOrName: string, realm?: string): Promise; findManyBy(where: Record): Promise; findOneBy(where: Record): Promise; create(data: Partial): T; merge(entity: T, data: Partial): T; save(entity: T): Promise; remove(entity: T): Promise; validateJoinColumns(data: Partial): Promise; } //#endregion //#region src/crypto/hash/compare.d.ts export declare function compare(value: string, hashedValue: string): Promise; //#endregion //#region src/crypto/hash/hash.d.ts export declare function hash(str: string, rounds?: number): Promise; //#endregion //#region src/crypto/key/asymmetric/constants.d.ts export declare enum CryptoAsymmetricAlgorithm { RSA_PSS = "RSA-PSS", RSASSA_PKCS1_V1_5 = "RSASSA-PKCS1-v1_5", RSA_OAEP = "RSA-OAEP", ECDSA = "ECDSA", ECDH = "ECDH" } //#endregion //#region src/crypto/key/base.d.ts export declare abstract class BaseKey { protected key: CryptoKey; constructor(cryptoKey: CryptoKey); toArrayBuffer(): Promise; toUint8Array(): Promise; toBase64(): Promise; toJWK(): Promise; } //#endregion //#region src/crypto/key/asymmetric/types.d.ts export type RSAKeyPairCreateOptions = RsaHashedKeyGenParams & { name: CryptoAsymmetricAlgorithm.RSA_OAEP | CryptoAsymmetricAlgorithm.RSA_PSS | CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5; }; export type RSAKeyPairCreateOptionsInput = Partial & { name: CryptoAsymmetricAlgorithm.RSA_OAEP | CryptoAsymmetricAlgorithm.RSA_PSS | CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5; }; export type ECKeyPairCreateOptions = EcKeyGenParams & { name: CryptoAsymmetricAlgorithm.ECDSA | CryptoAsymmetricAlgorithm.ECDH; }; export type ECKeyPairCreateOptionsInput = Partial & { name: CryptoAsymmetricAlgorithm.ECDSA | CryptoAsymmetricAlgorithm.ECDH; }; export type AsymmetricKeyPairCreateOptions = RSAKeyPairCreateOptions | ECKeyPairCreateOptions; export type AsymmetricKeyPairCreateOptionsInput = RSAKeyPairCreateOptionsInput | ECKeyPairCreateOptionsInput; export type RSAKeyPairImportOptions = RsaHashedImportParams & { name: CryptoAsymmetricAlgorithm.RSA_OAEP | CryptoAsymmetricAlgorithm.RSA_PSS | CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5; }; export type RSAKeyPairImportOptionsInput = Partial & { name: CryptoAsymmetricAlgorithm.RSA_OAEP | CryptoAsymmetricAlgorithm.RSA_PSS | CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5; }; export type ECKeyPairImportOptions = EcKeyImportParams & { name: CryptoAsymmetricAlgorithm.ECDSA | CryptoAsymmetricAlgorithm.ECDH; }; export type ECKeyPairImportOptionsInput = Partial & { name: CryptoAsymmetricAlgorithm.ECDSA | CryptoAsymmetricAlgorithm.ECDH; }; export type AsymmetricKeyPairImportOptions = RSAKeyPairImportOptions | ECKeyPairImportOptions; export type AsymmetricKeyImportOptionsInput = RSAKeyPairImportOptionsInput | ECKeyPairImportOptionsInput; export type AsymmetricKeyImportContext = { format: 'spki' | 'pkcs8'; key: T; options: AsymmetricKeyImportOptionsInput; }; //#endregion //#region src/crypto/key/asymmetric/module.d.ts export declare class AsymmetricKey extends BaseKey { toPem(): Promise; static fromPem(ctx: AsymmetricKeyImportContext): Promise; static fromBase64(ctx: AsymmetricKeyImportContext): Promise; static fromArrayBuffer(ctx: AsymmetricKeyImportContext): Promise; static buildImportOptionsForJWTAlgorithm(alg: `${JWTAlgorithm}`): { name: CryptoAsymmetricAlgorithm; hash: string; namedCurve?: undefined; } | { name: CryptoAsymmetricAlgorithm; namedCurve: string; hash?: undefined; }; } //#endregion //#region src/crypto/key/asymmetric/check.d.ts export declare function isAsymmetricAlgorithm(input: string): input is CryptoAsymmetricAlgorithm; //#endregion //#region src/crypto/key/asymmetric/create.d.ts export declare function createAsymmetricKeyPair(options: AsymmetricKeyPairCreateOptionsInput): Promise; //#endregion //#region src/crypto/key/asymmetric/helpers/wrap.d.ts export declare function encodePKCS8ToPEM(base64: string): string; export declare function encodeSPKIToPem(input: string): string; export declare function decodePemToPKCS8(input: string): string; export declare function decodePemToSpki(input: string): string; //#endregion //#region src/crypto/key/asymmetric/key-usages.d.ts /** * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages */ export declare function getKeyUsagesForAsymmetricAlgorithm(name: string, format?: Exclude): KeyUsage[]; //#endregion //#region src/crypto/key/asymmetric/normalize.d.ts export declare function normalizeAsymmetricKeyPairCreateOptions(options: AsymmetricKeyPairCreateOptionsInput): AsymmetricKeyPairCreateOptions; export declare function normalizeAsymmetricKeyImportOptions(options: AsymmetricKeyImportOptionsInput): AsymmetricKeyPairImportOptions; //#endregion //#region src/crypto/key/symmetric/constants.d.ts export declare enum SymmetricAlgorithm { HMAC = "HMAC", AES_CTR = "AES-CTR", AES_CBC = "AES-CBC", AES_GCM = "AES-GCM" } //#endregion //#region src/crypto/key/symmetric/check.d.ts export declare function isSymmetricAlgorithm(input: string): input is SymmetricAlgorithm; //#endregion //#region src/crypto/key/symmetric/types.d.ts export type AESKeyCreateOptions = AesKeyGenParams & { name: `${SymmetricAlgorithm.AES_CBC}` | `${SymmetricAlgorithm.AES_CTR}` | `${SymmetricAlgorithm.AES_GCM}`; }; export type AESKeyCreateOptionsInput = Partial & { name: `${SymmetricAlgorithm.AES_CBC}` | `${SymmetricAlgorithm.AES_CTR}` | `${SymmetricAlgorithm.AES_GCM}`; }; export type HMACKeyCreateOptions = HmacKeyGenParams & { name: `${SymmetricAlgorithm.HMAC}`; }; export type HMACKeyCreateOptionsInput = Partial & { name: `${SymmetricAlgorithm.HMAC}`; }; export type SymmetricKeyCreateOptions = AESKeyCreateOptions | HMACKeyCreateOptions; export type SymmetricKeyCreateOptionsInput = AESKeyCreateOptionsInput | HMACKeyCreateOptionsInput; export type AESKeyImportOptions = AesKeyAlgorithm & { name: `${SymmetricAlgorithm.AES_CBC}` | `${SymmetricAlgorithm.AES_CTR}` | `${SymmetricAlgorithm.AES_GCM}`; }; export type HMACKeyImportOptions = HmacImportParams & { name: `${SymmetricAlgorithm.HMAC}`; }; export type HMACKeyImportOptionsInput = Partial & { name: `${SymmetricAlgorithm.HMAC}`; }; export type SymmetricKeyImportOptions = AESKeyImportOptions | HMACKeyImportOptions; export type SymmetricKeyImportOptionsInput = AESKeyImportOptions | HMACKeyImportOptionsInput; export type SymmetricKeyImportContext = { format: 'raw'; key: T; options: SymmetricKeyImportOptionsInput; }; //#endregion //#region src/crypto/key/symmetric/module.d.ts export declare class SymmetricKey extends BaseKey { static fromBase64(ctx: SymmetricKeyImportContext): Promise; static fromArrayBuffer(ctx: SymmetricKeyImportContext): Promise; static buildImportOptionsForJWTAlgorithm(alg: `${JWTAlgorithm}`): { name: SymmetricAlgorithm; hash: string; }; } //#endregion //#region src/crypto/key/symmetric/create.d.ts export declare function createSymmetricKey(input: SymmetricKeyCreateOptionsInput): Promise; //#endregion //#region src/crypto/key/symmetric/key-usages.d.ts export declare function getKeyUsagesForSymmetricAlgorithm(name: string): KeyUsage[]; //#endregion //#region src/crypto/json-web-token/extract.d.ts /** * Decode a JWT token with no verification. * * @param token * * @throws JWTError */ export declare function extractTokenHeader(token: string): JWTHeader; /** * @param token * * @throws JWTError */ export declare function extractTokenPayload(token: string): JWTClaims; //#endregion //#region src/crypto/json-web-token/types.d.ts export type TokenRSAAlgorithm = `${JWTAlgorithm.RS256}` | `${JWTAlgorithm.RS384}` | `${JWTAlgorithm.RS512}` | `${JWTAlgorithm.PS256}` | `${JWTAlgorithm.PS384}` | `${JWTAlgorithm.PS512}`; export type TokenECAlgorithm = `${JWTAlgorithm.ES256}` | `${JWTAlgorithm.ES384}`; export type TokenOCTAlgorithm = `${JWTAlgorithm.HS256}` | `${JWTAlgorithm.HS384}` | `${JWTAlgorithm.HS512}`; //#endregion //#region src/crypto/json-web-token/sign/types.d.ts export type TokenSignBaseOptions = { keyId?: string; }; export type TokenSignRSAOptions = TokenSignBaseOptions & { type: `${JWKType.RSA}` | JWKType.RSA; algorithm?: TokenRSAAlgorithm; /** * base64 encoded private key. */ key: string | CryptoKey; }; export type TokenSignECOptions = TokenSignBaseOptions & { type: `${JWKType.EC}` | JWKType.EC; algorithm?: TokenECAlgorithm; /** * base64 encoded private key. */ key: string | CryptoKey; }; export type TokenSignOCTOptions = TokenSignBaseOptions & { type: `${JWKType.OCT}` | JWKType.OCT; algorithm?: TokenOCTAlgorithm; key: string | CryptoKey; }; export type TokenSignOptions = TokenSignRSAOptions | TokenSignECOptions | TokenSignOCTOptions; //#endregion //#region src/crypto/json-web-token/sign/module.d.ts export declare function signToken(claims: JWTClaims, context: TokenSignOptions): Promise; //#endregion //#region src/crypto/json-web-token/verify/types.d.ts export type TokenVerifyRSAOptions = { type: `${JWKType.RSA}` | JWKType.RSA; algorithms?: TokenRSAAlgorithm[]; /** * base64 encoded public key. */ key: string | CryptoKey; }; export type TokenVerifyECOptions = { type: `${JWKType.EC}` | JWKType.EC; algorithms?: TokenECAlgorithm[]; /** * base64 encoded public key. */ key: string | CryptoKey; }; export type TokenVerifyOCTOptions = { type: `${JWKType.OCT}` | JWKType.OCT; algorithms?: TokenOCTAlgorithm[]; key: string | CryptoKey; }; export type TokenVerifyOptions = TokenVerifyRSAOptions | TokenVerifyECOptions | TokenVerifyOCTOptions; //#endregion //#region src/crypto/json-web-token/verify/module.d.ts /** * Verify JWT. * * @param token * @param context * * @throws OAuth2Error */ export declare function verifyToken(token: string, context: TokenVerifyOptions, options?: { ignoreExpiry?: boolean; }): Promise; //#endregion //#region src/crypto/symmetric-cipher/types.d.ts /** * Reversible symmetric encryption for secrets that must be recoverable * at rest (e.g. TOTP seeds — unlike passwords, they cannot be one-way * hashed because verification needs the plaintext). */ export interface ISymmetricCipher { encrypt(plain: string): Promise; decrypt(blob: string): Promise; } //#endregion //#region src/crypto/symmetric-cipher/module.d.ts /** * AES-256-GCM cipher over a base64-encoded 32-byte key. Blob format: * base64(iv ‖ ciphertext ‖ tag) — WebCrypto appends the GCM tag to the * ciphertext, so the layout is iv (12 bytes) followed by the sealed rest. */ export declare class SymmetricCipher implements ISymmetricCipher { protected key: Promise; constructor(key: string); encrypt(plain: string): Promise; decrypt(blob: string): Promise; } //#endregion //#region src/domain-event/types.d.ts export type DomainEventChannelName = string | ((id?: string | number) => string); export type DomainEventDestination = { namespace?: string; channel: DomainEventChannelName; }; export type DomainEventDestinations = DomainEventDestination[]; export type DomainEventPublishContext = { content: T; destinations: DomainEventDestinations; /** * Pre-mutation snapshot of the entity for `updated` events. Lives on the * publish CONTEXT (never inside `content`): `content` is the shared * realtime wire payload and must never carry previous state to * redis/socket consumers — only in-process handlers (e.g. the audit * entity-event bridge) may read it. */ dataPrevious?: Record; /** * The transaction the publishing write rides, as an opaque handle (this * package knows no persistence): an in-process handler that persists * joins it instead of taking a second connection (#3539). Wire handlers * ignore it. */ transaction?: unknown; }; export interface IDomainEventHandler { handle(ctx: DomainEventPublishContext): Promise; dispose?(): Promise; } export interface IDomainEventPublisher { publish(ctx: DomainEventPublishContext): Promise; safePublish(ctx: DomainEventPublishContext): Promise; } //#endregion //#region src/domain-event/handlers/redis/module.d.ts export declare class DomainEventRedisHandler implements IDomainEventHandler { protected driver: Client; constructor(input: RedisClientCreateInput); handle(ctx: DomainEventPublishContext): Promise; } //#endregion //#region src/domain-event/handlers/socket/module.d.ts export declare class DomainEventSocketHandler implements IDomainEventHandler { protected driver: Emitter; constructor(input: RedisClientCreateInput); handle(ctx: DomainEventPublishContext): Promise; } //#endregion //#region src/logger/types.d.ts export type LoggerLevelFn = { (message: string, ...meta: any[]): OUT; (message: any): OUT; }; export type Logger = { error: LoggerLevelFn; warn: LoggerLevelFn; info: LoggerLevelFn; http: LoggerLevelFn; verbose: LoggerLevelFn; debug: LoggerLevelFn; }; export type LoggerCreateContext = { env: string; directory?: string; }; //#endregion //#region src/logger/module.d.ts export declare function createNoopLogger(): Logger; export declare function createLogger(context: LoggerCreateContext): Logger; //#endregion //#region src/domain-event/module.d.ts export type DomainEventPublisherContext = { logger?: Logger; }; export declare class DomainEventPublisher implements IDomainEventPublisher { protected handlers: Set; protected logger?: Logger; constructor(ctx?: DomainEventPublisherContext); register(handler: IDomainEventHandler): void; dispose(): Promise; safePublish(ctx: DomainEventPublishContext): Promise; publish(ctx: DomainEventPublishContext): Promise; } //#endregion //#region src/utils/has-property.d.ts export declare function hasOwnProperty, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record; //#endregion export { RedisClient, type RedisClientOptions, RedisJsonAdapter, RedisWatcher, buildRedisKeyPath, escapeRedisKey, parseRedisKeyPath }; //# sourceMappingURL=index.d.mts.map