# ===============================================
# AUTHENTICATION
# ===============================================

extend type Query {
  apiKeys: [AuthenticationApiKey]

  apiState: Boolean

  authStrategies: [AuthenticationStrategy]

  authActiveStrategies(
    enabledOnly: Boolean
  ): [AuthenticationActiveStrategy]

  authSiteStrategies(
    siteId: UUID!
    visibleOnly: Boolean
  ): [AuthenticationSiteStrategy]
}

extend type Mutation {
  createApiKey(
    name: String!
    expiration: String!
    groups: [UUID]!
  ): AuthenticationCreateApiKeyResponse

  login(
    username: String!
    password: String!
    strategyId: UUID!
    siteId: UUID!
  ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60)

  loginTFA(
    continuationToken: String!
    securityCode: String!
    strategyId: UUID!
    siteId: UUID!
    setup: Boolean
  ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60)

  setupTFA(
    strategyId: UUID!
    siteId: UUID!
  ): AuthenticationSetupTFAResponse

  deactivateTFA(
    strategyId: UUID!
  ): DefaultResponse

  setupPasskey(
    siteId: UUID!
  ): AuthenticationSetupPasskeyResponse

  finalizePasskey(
    registrationResponse: JSON!
    name: String!
  ): DefaultResponse

  deactivatePasskey(
    id: UUID!
  ): DefaultResponse

  authenticatePasskeyGenerate(
    email: String!
    siteId: UUID!
  ): AuthenticationPasskeyResponse @rateLimit(limit: 5, duration: 60)

  authenticatePasskeyVerify(
    authResponse: JSON!
  ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60)

  changePassword(
    continuationToken: String
    currentPassword: String
    newPassword: String!
    strategyId: UUID!
    siteId: UUID!
  ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60)

  forgotPassword(
    email: String!
  ): DefaultResponse @rateLimit(limit: 3, duration: 60)

  register(
    email: String!
    password: String!
    name: String!
  ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60)

  refreshToken(
    token: String!
  ): AuthenticationTokenResponse @rateLimit(limit: 30, duration: 60)

  revokeApiKey(
    id: UUID!
  ): DefaultResponse

  setApiState(
    enabled: Boolean!
  ): DefaultResponse

  updateAuthStrategies(
    strategies: [AuthenticationStrategyInput]!
  ): DefaultResponse

  regenerateCertificates: DefaultResponse

  resetGuestUser: DefaultResponse
}

# -----------------------------------------------
# TYPES
# -----------------------------------------------

type AuthenticationStrategy {
  key: String
  props: JSON
  refs: JSON
  title: String
  description: String
  isAvailable: Boolean
  useForm: Boolean
  usernameType: String
  logo: String
  color: String
  vendor: String
  website: String
  icon: String
}

type AuthenticationActiveStrategy {
  id: UUID
  strategy: AuthenticationStrategy
  displayName: String
  isEnabled: Boolean
  config: JSON
  registration: Boolean
  allowedEmailRegex: String
  autoEnrollGroups: [UUID]
}

type AuthenticationSiteStrategy {
  id: UUID
  activeStrategy: AuthenticationActiveStrategy
  isVisible: Boolean
}

type AuthenticationAuthResponse {
  operation: Operation
  jwt: String
  nextAction: AuthenticationNextAction
  continuationToken: String
  redirect: String
  tfaQRImage: String
}

type AuthenticationTokenResponse {
  operation: Operation
  jwt: String
}

type AuthenticationSetupTFAResponse {
  operation: Operation
  continuationToken: String
  tfaQRImage: String
}

type AuthenticationSetupPasskeyResponse {
  operation: Operation
  registrationOptions: JSON
}

type AuthenticationPasskeyResponse {
  operation: Operation
  authOptions: JSON
}

input AuthenticationStrategyInput {
  key: String!
  strategyKey: String!
  config: JSON!
  displayName: String!
  order: Int!
  isEnabled: Boolean!
  registration: Boolean!
  allowedEmailRegex: String!
  autoEnrollGroups: [UUID]!
}

type AuthenticationApiKey {
  id: UUID
  name: String
  keyShort: String
  expiration: Date
  createdAt: Date
  updatedAt: Date
  isRevoked: Boolean
}

type AuthenticationCreateApiKeyResponse {
  operation: Operation
  key: String
}

enum AuthenticationNextAction {
  changePassword
  setupTfa
  provideTfa
  redirect
}