import * as _alepha_core2 from "alepha";
import * as _alepha_core3 from "alepha";
import * as _alepha_core1 from "alepha";
import * as _alepha_core0 from "alepha";
import { Alepha, Descriptor, KIND, Static } from "alepha";
import { DateTimeProvider, Duration, DurationLike } from "alepha/datetime";
import { CryptoKey, FlattenedJWSInput, JSONWebKeySet, JWSHeaderParameters, JWTHeaderParameters, JWTPayload, JWTVerifyResult, KeyObject } from "jose";
import * as _sinclair_typebox0 from "@sinclair/typebox";
import * as _sinclair_typebox13 from "@sinclair/typebox";
import * as _sinclair_typebox23 from "@sinclair/typebox";
import { JWTVerifyOptions } from "jose/jwt/verify";

//#region src/schemas/userAccountInfoSchema.d.ts
declare const userAccountInfoSchema: _sinclair_typebox0.TObject<{
  id: _sinclair_typebox0.TString;
  name: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
  email: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
  picture: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
  organizations: _sinclair_typebox0.TOptional<_sinclair_typebox0.TArray<_sinclair_typebox0.TString>>;
  roles: _sinclair_typebox0.TOptional<_sinclair_typebox0.TArray<_sinclair_typebox0.TString>>;
}>;
type UserAccountInfo = Static<typeof userAccountInfoSchema>;
//# sourceMappingURL=userAccountInfoSchema.d.ts.map
//#endregion
//#region src/interfaces/UserAccountToken.d.ts
interface UserAccountToken extends UserAccountInfo {
  /**
   * Access token for the user.
   */
  token?: string;
  realm?: string;
  /**
   * Is user dedicated to his own resources for this scope ?
   * Mostly, Admin is false and Customer is true.
   */
  ownership?: string | boolean;
}
//# sourceMappingURL=UserAccountToken.d.ts.map
//#endregion
//#region src/schemas/permissionSchema.d.ts
declare const permissionSchema: _sinclair_typebox13.TObject<{
  name: _sinclair_typebox13.TString;
  group: _sinclair_typebox13.TOptional<_sinclair_typebox13.TString>;
  description: _sinclair_typebox13.TOptional<_sinclair_typebox13.TString>;
  method: _sinclair_typebox13.TOptional<_sinclair_typebox13.TString>;
  path: _sinclair_typebox13.TOptional<_sinclair_typebox13.TString>;
}>;
type Permission = Static<typeof permissionSchema>;
//# sourceMappingURL=permissionSchema.d.ts.map
//#endregion
//#region src/schemas/roleSchema.d.ts
declare const roleSchema: _sinclair_typebox23.TObject<{
  name: _sinclair_typebox23.TString;
  description: _sinclair_typebox23.TOptional<_sinclair_typebox23.TString>;
  default: _sinclair_typebox23.TOptional<_sinclair_typebox23.TBoolean>;
  permissions: _sinclair_typebox23.TArray<_sinclair_typebox23.TObject<{
    name: _sinclair_typebox23.TString;
    ownership: _sinclair_typebox23.TOptional<_sinclair_typebox23.TBoolean>;
    exclude: _sinclair_typebox23.TOptional<_sinclair_typebox23.TArray<_sinclair_typebox23.TString>>;
  }>>;
}>;
type Role = Static<typeof roleSchema>;
//# sourceMappingURL=roleSchema.d.ts.map
//#endregion
//#region src/providers/JwtProvider.d.ts
/**
 * Provides utilities for working with JSON Web Tokens (JWT).
 */
declare class JwtProvider {
  protected readonly log: _alepha_core2.Logger;
  protected readonly keystore: KeyLoaderHolder[];
  protected readonly dateTimeProvider: DateTimeProvider;
  protected readonly encoder: TextEncoder;
  /**
   * Adds a key loader to the embedded keystore.
   *
   * @param name
   * @param secretKeyOrJwks
   */
  setKeyLoader(name: string, secretKeyOrJwks: string | JSONWebKeySet): void;
  /**
   * Retrieves the payload from a JSON Web Token (JWT).
   *
   * @param token - The JWT to extract the payload from.
   *
   * @return A Promise that resolves with the payload object from the token.
   */
  parse(token: string, keyName?: string, options?: JWTVerifyOptions): Promise<JwtParseResult>;
  /**
   * Creates a JWT token with the provided payload and secret key.
   *
   * @param payload - The payload to be encoded in the token.
   * 	It should include the `realm_access` property which contains an array of roles.
   * @param keyName - The name of the key to use when signing the token.
   *
   * @returns The signed JWT token.
   */
  create(payload: ExtendedJWTPayload, keyName?: string, signOptions?: JwtSignOptions): Promise<string>;
  /**
   * Determines if the provided key is a secret key.
   *
   * @param key
   * @protected
   */
  protected isSecretKey(key: string): boolean;
}
type KeyLoader = (protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput) => Promise<CryptoKey | KeyObject>;
interface KeyLoaderHolder {
  name: string;
  keyLoader: KeyLoader;
  secretKey?: string;
}
interface JwtSignOptions {
  header?: Partial<JWTHeaderParameters>;
}
interface ExtendedJWTPayload extends JWTPayload {
  name?: string;
  roles?: string[];
  email?: string;
  organizations?: string[];
  realm_access?: {
    roles: string[];
  };
}
interface JwtParseResult {
  keyName: string;
  result: JWTVerifyResult<ExtendedJWTPayload>;
}
//# sourceMappingURL=JwtProvider.d.ts.map
//#endregion
//#region src/providers/SecurityProvider.d.ts
declare const envSchema: _alepha_core3.TObject<{
  SECURITY_SECRET_KEY: _alepha_core3.TString;
}>;
declare module "alepha" {
  interface Env extends Partial<Static<typeof envSchema>> {}
}
declare class SecurityProvider {
  protected readonly UNKNOWN_USER_NAME = "Unknown User";
  protected readonly PERMISSION_REGEXP: RegExp;
  protected readonly PERMISSION_REGEXP_WILDCARD: RegExp;
  protected readonly log: _alepha_core3.Logger;
  protected readonly jwt: JwtProvider;
  protected readonly env: {
    SECURITY_SECRET_KEY: string;
  };
  protected readonly alepha: Alepha;
  /**
   * The permissions configured for the security provider.
   */
  protected readonly permissions: Permission[];
  /**
   * The realms configured for the security provider.
   */
  protected readonly realms: Realm[];
  protected configure: _alepha_core3.HookDescriptor<"start">;
  protected ready: _alepha_core3.HookDescriptor<"ready">;
  /**
   * Adds a role to one or more realms.
   *
   * @param role
   * @param realms
   */
  createRole(role: Role, ...realms: string[]): Role;
  /**
   * Adds a permission to the security provider.
   *
   * @param raw - The permission to add.
   */
  createPermission(raw: Permission | string): Permission;
  createRealm(realm: Realm): void;
  /**
   * Updates the roles for a realm then synchronizes the user account provider if available.
   *
   * Only available when the app is started.
   *
   * @param realm - The realm to update the roles for.
   * @param roles - The roles to update.
   */
  updateRealm(realm: string, roles: Role[]): Promise<void>;
  /**
   * Creates a user account from the provided payload.
   *
   * @param payload - The payload to create the user account from.
   * @param [realmName] - The realm containing the roles. Default is all.
   *
   * @returns The user info created from the payload.
   */
  createUserFromPayload(payload: JWTPayload, realmName?: string): UserAccountInfo;
  /**
   * Checks if the user has the specified permission.
   *
   * Bonus: we check also if the user has "ownership" flag.
   *
   * @param permissionLike - The permission to check for.
   * @param roleEntries - The roles to check for the permission.
   */
  checkPermission(permissionLike: string | Permission, ...roleEntries: string[]): SecurityCheckResult;
  /**
   * Creates a user account from the provided payload.
   *
   * @param headerOrToken
   * @param permissionLike
   */
  createUserFromToken(headerOrToken?: string, options?: {
    permission?: Permission | string;
    realm?: string;
    verify?: JWTVerifyOptions;
  }): Promise<UserAccountToken>;
  /**
   * Checks if a user has a specific role.
   *
   * @param roleName - The role to check for.
   * @param permission - The permission to check for.
   * @returns True if the user has the role, false otherwise.
   */
  can(roleName: string, permission: string | Permission): boolean;
  /**
   * Checks if a user has ownership of a specific permission.
   */
  ownership(roleName: string, permission: string | Permission): string | boolean | undefined;
  /**
   * Converts a permission object to a string.
   *
   * @param permission
   */
  permissionToString(permission: Permission | string): string;
  getRealms(): Realm[];
  /**
   * Retrieves the user account from the provided user ID.
   *
   * @param realm
   */
  getRoles(realm?: string): Role[];
  /**
   * Returns all permissions.
   *
   * @param user - Filter permissions by user.
   *
   * @return An array containing all permissions.
   */
  getPermissions(user?: {
    roles?: Array<Role | string>;
    realm?: string;
  }): Permission[];
  /**
   * Retrieves the user ID from the provided payload object.
   *
   * @param payload - The payload object from which to extract the user ID.
   * @return The user ID as a string.
   */
  getIdFromPayload(payload: Record<string, any>): string;
  /**
   * Retrieves the roles from the provided payload object.
   * @param payload - The payload object from which to extract the roles.
   * @return An array of role strings.
   */
  getRolesFromPayload(payload: Record<string, any>): string[];
  getPictureFromPayload(payload: Record<string, any>): string | undefined;
  getEmailFromPayload(payload: Record<string, any>): string | undefined;
  /**
   * Returns the name from the given payload.
   *
   * @param payload - The payload object.
   * @returns The name extracted from the payload, or an empty string if the payload is falsy or no name is found.
   */
  getNameFromPayload(payload: Record<string, any>): string;
  getOrganizationsFromPayload(payload: Record<string, any>): string[] | undefined;
}
/**
 * A realm definition.
 */
interface Realm {
  name: string;
  roles: Role[];
  /**
   * The secret key for the realm.
   *
   * Can be also a JWKS URL.
   */
  secret?: string | JSONWebKeySet | (() => string);
  /**
   * Attach a user provider to the realm.
   *
   * This is useful when you want to use a custom user provider for a specific realm.
   */
  userAccountProvider?: SecurityUserAccountProvider;
  onLoadUser?: (user: UserAccountInfo) => Promise<void> | void;
  /**
   * Function to create a user profile from the raw JWT user data.
   */
  profile?: (raw: Record<string, any>) => UserAccountInfo;
}
interface SecurityUserAccountProvider {
  jwks: string | undefined;
  synchronize(config: RealmConfig): Promise<void>;
}
interface SecurityCheckResult {
  isAuthorized: boolean;
  ownership: string | boolean | undefined;
}
interface RealmConfig {
  roles?: Array<Role>;
  smtp?: {
    host?: string;
  };
}
//#endregion
//#region src/descriptors/$permission.d.ts
/**
 * Create a new permission.
 */
declare const $permission: {
  (options?: PermissionDescriptorOptions): PermissionDescriptor;
  [KIND]: typeof PermissionDescriptor;
};
interface PermissionDescriptorOptions {
  /**
   * Name of the permission. Use Property name is not provided.
   */
  name?: string;
  /**
   * Group of the permission. Use Class name is not provided.
   */
  group?: string;
  /**
   * Describe the permission.
   */
  description?: string;
}
declare class PermissionDescriptor extends Descriptor<PermissionDescriptorOptions> {
  protected readonly securityProvider: SecurityProvider;
  get name(): string;
  get group(): string;
  protected onInit(): void;
  /**
   * Check if the user has the permission.
   */
  can(user: UserAccountInfo): boolean;
}
//# sourceMappingURL=$permission.d.ts.map
//#endregion
//#region src/descriptors/$realm.d.ts
/**
 * Create a new realm.
 */
declare const $realm: {
  (options: RealmDescriptorOptions): RealmDescriptor;
  [KIND]: typeof RealmDescriptor;
};
type RealmDescriptorOptions = {
  /**
   * Define the realm name.
   * If not provided, it will use the property key.
   */
  name?: string;
  /**
   * Short description about the realm.
   */
  description?: string;
  /**
   * All roles available in the realm. Role is a string (role name) or a Role object (embedded role).
   */
  roles?: Array<string | Role>;
  settings?: RealmSettings;
  /**
   * Parse the JWT payload to create a user account info.
   */
  profile?: (jwtPayload: Record<string, any>) => UserAccountInfo;
} & (RealmInternal | RealmExternal);
interface RealmSettings {
  accessToken?: {
    /**
     * Lifetime of the access token.
     * @default 15 minutes
     */
    expiration?: DurationLike;
  };
  refreshToken?: {
    /**
     * Lifetime of the refresh token.
     * @default 30 days
     */
    expiration?: DurationLike;
    /**
     * If true, no refresh token will be created.
     */
    disabled?: boolean;
    create?: (user: UserAccountInfo, refreshToken?: string) => Promise<{
      refresh_token: string;
      expires_in: number;
    }>;
  };
}
type RealmInternal = {
  /**
   * Internal secret to sign JWT tokens and verify them.
   */
  secret: string;
};
interface RealmExternal {
  /**
   * URL to the JWKS (JSON Web Key Set) to verify JWT tokens from external providers.
   */
  jwks: (() => string) | JSONWebKeySet;
  /**
   * Attach a user account provider to the realm to manage roles.
   *
   * For example, you can use a KeycloakUserProvider to automatically create/update realm roles inside Keycloak.
   */
  userAccountProvider?: SecurityUserAccountProvider | (() => SecurityUserAccountProvider);
}
declare class RealmDescriptor extends Descriptor<RealmDescriptorOptions> {
  protected readonly securityProvider: SecurityProvider;
  protected readonly dateTimeProvider: DateTimeProvider;
  protected readonly jwt: JwtProvider;
  protected readonly log: _alepha_core1.Logger;
  get name(): string;
  get accessTokenExpiration(): Duration;
  get refreshTokenExpiration(): Duration;
  protected onInit(): void;
  /**
   * Get all roles in the realm.
   */
  getRoles(): Role[];
  /**
   * Set all roles in the realm.
   */
  setRoles(roles: Role[]): Promise<void>;
  /**
   * Get a role by name, throws an error if not found.
   */
  getRoleByName(name: string): Role;
  parseToken(token: string): Promise<JWTPayload>;
  /**
   * Create a token for the subject.
   */
  createToken(user: UserAccountInfo, refreshToken?: string): Promise<AccessTokenResponse>;
}
interface CreateTokenOptions {
  sub: string;
  roles?: string[];
  email?: string;
}
interface AccessTokenResponse {
  access_token: string;
  token_type: string;
  expires_in?: number;
  issued_at: number;
  refresh_token?: string;
  refresh_token_expires_in?: number;
  scope?: string;
}
//# sourceMappingURL=$realm.d.ts.map
//#endregion
//#region src/descriptors/$role.d.ts
/**
 * Create a new role.
 */
declare const $role: {
  (options?: RoleDescriptorOptions): RoleDescriptor;
  [KIND]: typeof RoleDescriptor;
};
interface RoleDescriptorOptions {
  /**
   * Name of the role.
   */
  name?: string;
  /**
   * Describe the role.
   */
  description?: string;
  realm?: string | RealmDescriptor;
  permissions?: Array<string | {
    name: string;
    ownership?: boolean;
  }>;
}
declare class RoleDescriptor extends Descriptor<RoleDescriptorOptions> {
  protected readonly securityProvider: SecurityProvider;
  get name(): string;
  protected onInit(): void;
  /**
   * Get the realm of the role.
   */
  get realm(): string | RealmDescriptor | undefined;
}
//# sourceMappingURL=$role.d.ts.map
//#endregion
//#region src/descriptors/$serviceAccount.d.ts
/**
 * Allow to get an access token for a service account.
 *
 * You have some options to configure the service account:
 * - a OAUTH2 URL using client credentials grant type
 * - a JWT secret shared between the services
 *
 * @example
 * ```ts
 * import { $serviceAccount } from "alepha/security";
 *
 * class MyService {
 *   serviceAccount = $serviceAccount({
 *     oauth2: {
 *       url: "https://example.com/oauth2/token",
 *       clientId: "your-client-id",
 *       clientSecret: "your-client-secret",
 *     }
 *   });
 *
 *   async fetchData() {
 *     const token = await this.serviceAccount.token();
 *     // or
 *     const response = await this.serviceAccount.fetch("https://api.example.com/data");
 *   }
 * }
 * ```
 */
declare const $serviceAccount: (options: ServiceAccountDescriptorOptions) => ServiceAccountDescriptor;
type ServiceAccountDescriptorOptions = {
  gracePeriod?: number;
} & ({
  oauth2: Oauth2ServiceAccountDescriptorOptions;
} | {
  realm: RealmDescriptor;
  user: UserAccountInfo;
});
interface Oauth2ServiceAccountDescriptorOptions {
  /**
   * Get Token URL.
   */
  url: string;
  /**
   * Client ID.
   */
  clientId: string;
  /**
   * Client Secret.
   */
  clientSecret: string;
}
interface ServiceAccountDescriptor {
  token: () => Promise<string>;
}
interface ServiceAccountStore {
  response?: AccessTokenResponse;
}
//# sourceMappingURL=$serviceAccount.d.ts.map
//#endregion
//#region src/errors/InvalidPermissionError.d.ts
declare class InvalidPermissionError extends Error {
  constructor(name: string);
}
//# sourceMappingURL=InvalidPermissionError.d.ts.map
//#endregion
//#region src/errors/SecurityError.d.ts
declare class SecurityError extends Error {
  name: string;
  readonly status = 403;
}
//# sourceMappingURL=SecurityError.d.ts.map
//#endregion
//#region src/providers/CryptoProvider.d.ts
declare class CryptoProvider {
  hashPassword(password: string): Promise<string>;
  verifyPassword(password: string, stored: string): Promise<boolean>;
}
//# sourceMappingURL=CryptoProvider.d.ts.map

//#endregion
//#region src/index.d.ts
declare module "alepha" {
  interface Hooks {
    "security:user:created": {
      realm: string;
      user: UserAccountInfo;
    };
  }
}
/**
 * Provides comprehensive authentication and authorization capabilities with JWT tokens, role-based access control, and user management.
 *
 * The security module enables building secure applications using descriptors like `$realm`, `$role`, and `$permission`
 * on class properties. It offers JWT-based authentication, fine-grained permissions, service accounts, and seamless
 * integration with various authentication providers and user management systems.
 *
 * @see {@link $realm}
 * @see {@link $role}
 * @see {@link $permission}
 * @module alepha.security
 */
declare const AlephaSecurity: _alepha_core0.Service<_alepha_core0.Module>;
//# sourceMappingURL=index.d.ts.map

//#endregion
export { $permission, $realm, $role, $serviceAccount, AccessTokenResponse, AlephaSecurity, CreateTokenOptions, CryptoProvider, ExtendedJWTPayload, InvalidPermissionError, JwtParseResult, JwtProvider, JwtSignOptions, KeyLoader, KeyLoaderHolder, Oauth2ServiceAccountDescriptorOptions, Permission, PermissionDescriptor, PermissionDescriptorOptions, Realm, RealmConfig, RealmDescriptor, RealmDescriptorOptions, RealmExternal, RealmInternal, RealmSettings, Role, RoleDescriptor, RoleDescriptorOptions, SecurityCheckResult, SecurityError, SecurityProvider, SecurityUserAccountProvider, ServiceAccountDescriptor, ServiceAccountDescriptorOptions, ServiceAccountStore, UserAccountInfo, UserAccountToken, permissionSchema, roleSchema, userAccountInfoSchema };
//# sourceMappingURL=index.d.ts.map