// Copyright © 2023 Ory Corp // SPDX-License-Identifier: Apache-2.0 import { Session as KratosSession } from "@ory/kratos-client" import { OryKratosConfiguration } from "../../shared/config" import { ConfigBuilder } from "./configHelpers" export interface MailMessage { fromAddress: string toAddresses: Array body: string subject: string } export type Strategy = "code" | "link" type app = "express" | "react" declare global { namespace Cypress { interface Chainable { /** * Delete mails from the email server. * * @param options */ deleteMail(options: { atLeast?: boolean }): Chainable /** * Adds end enables a WebAuth authenticator key. */ addVirtualAuthenticator(): Chainable /** * Fetch the browser's Ory Session. * * @param opts */ getSession(opts?: { expectAal?: "aal2" | "aal1" expectMethods?: Array< | "password" | "webauthn" | "lookup_secret" | "totp" | "code" | "passkey" > token?: string }): Chainable /** * Expect that the browser has no valid Ory Kratos Cookie Session. */ noSession(): Chainable> /** * Log a user in * * @param opts */ login(opts: { email: string password: string expectSession?: boolean cookieUrl?: string }): Chainable> /** * Sign up a user * * @param opts */ register(opts: { email: string password: string query?: { [key: string]: string } fields?: { [key: string]: any } }): Chainable> /** * Register a user with a code * * @param opts */ registerWithCode(opts: { email: string code?: string traits?: { [key: string]: any } query?: { [key: string]: string } expectedMailCount?: number }): Chainable> /** * Updates a user's settings using an API flow * * @param opts */ settingsApi(opts: { fields?: { [key: string]: any } }): Chainable> /** * Set the "privileged session lifespan" to a large value. */ longPrivilegedSessionTime(): Chainable /** * Return and optionally delete an email from the fake email server. * * @param opts */ getMail(opts: { removeMail?: boolean expectedCount?: number email?: string subject?: string body?: string }): Chainable performEmailVerification(opts?: { expect?: { email?: string; redirectTo?: string } strategy?: Strategy useLinkFromEmail?: boolean }): Chainable /** * Sets the Ory Kratos configuration profile. * * @param profile */ useConfigProfile(profile: string): Chainable /** * Register a new user with email + password via the API. * * Recommended to use if you need an Ory Session Token or alternatively the user created. * * @param opts */ registerApi(opts?: { email: string password: string fields: { [key: string]: string } }): Chainable /** * Submits a recovery flow via the API * * @param opts */ recoverApi(opts: { email: string; returnTo?: string }): Chainable /** * Submits a verification flow via the API * * @param opts */ verificationApi(opts: { email: string returnTo?: string strategy?: Strategy }): Chainable /** * Update the config file * * @param cb */ updateConfigFile(cb: (arg: OryKratosConfiguration) => any): Chainable /** * Submits a verification flow via the API * * @param opts */ verificationApiExpired(opts: { email: string strategy?: Strategy returnTo?: string }): Chainable /** * Sets the hook. * * @param hooks */ setupHooks( flow: | "registration" | "login" | "recovery" | "verification" | "settings", phase: "before" | "after", kind: "password" | "webauthn" | "oidc" | "code" | "passkey", hooks: Array<{ hook: string; config?: any }>, ): Chainable /** * Sets the post registration hook. * * @param hooks */ setPostPasswordRegistrationHooks( hooks: Array<{ hook: string; config?: any }>, ): Chainable /** * Sets the post code registration hook. * * @param hooks */ setPostCodeRegistrationHooks( hooks: Array<{ hook: string; config?: any }>, ): Chainable /** * Submits a verification flow via the Browser * * @param opts */ verificationBrowser(opts: { email: string returnTo?: string }): Chainable /** * Changes the config so that the login flow lifespan is very short. * * * Useful when testing expiry of login flows. * @see longLoginLifespan() */ shortLoginLifespan(): Chainable /** * Changes the config so that the login flow lifespan is very long. * * Useful when testing expiry of login flows. * * @see shortLoginLifespan() */ longLoginLifespan(): Chainable /** * Change the config so that `https://www.ory.com/` is a allowed return to URL. */ browserReturnUrlOry(): Chainable /** * Change the courier recovery invalid and valid templates to remote base64 strings */ remoteCourierRecoveryTemplates(): Chainable /** * Resets the remote courier templates for the given template type to their default values */ resetCourierTemplates( type: "recovery_code" | "recovery" | "verification", ): Chainable /** * Change the courier recovery code invalid and valid templates to remote base64 strings */ remoteCourierRecoveryCodeTemplates(): Chainable /** * Changes the config so that the registration flow lifespan is very short. * * Useful when testing expiry of registration flows. * * @see longRegisterLifespan() */ shortRegisterLifespan(): Chainable /** * Changes the config so that the registration flow lifespan is very long. * * Useful when testing expiry of registration flows. * * @see shortRegisterLifespan() */ longRegisterLifespan(): Chainable /** * Changes the config so that the settings privileged lifespan is very long. * * Useful when testing privileged settings flows. * * @see longPrivilegedSessionTime() */ shortPrivilegedSessionTime(): Chainable /** * Re-authenticates a user. * * @param opts */ reauth(opts: { expect: { email: string; success?: boolean } type: { email?: string; password?: string } }): Chainable /** * Change the config file to support lookup secrets * @param value */ useLookupSecrets(value: boolean): Chainable /** * Re-authenticates a user. * * @param opts */ reauthWithOtherAccount(opts: { previousUrl: string expect: { email: string; success?: boolean } type: { email?: string; password?: string } }): Chainable /** * Do not require 2fa for /session/whoami */ sessionRequiresNo2fa(): Chainable /** * Require 2fa for /session/whoami if available */ sessionRequires2fa(): Chainable /** * Like sessionRequires2fa but sets this also for settings */ requireStrictAal(): Chainable /** * Like sessionRequiresNo2fa but sets this also for settings */ useLaxAal(): Chainable /** * Gets the lookup codes from the settings page */ getLookupSecrets(): Chainable> /** * Expect the settings to be saved. */ expectSettingsSaved(): Chainable clearCookies( options?: Partial, ): Chainable /** * Submits a password form by clicking the button with method=password */ submitPasswordForm(): Chainable /** * Submits a profile form by clicking the button with method=profile */ submitProfileForm(app?: "mobile" | "express" | "react"): Chainable /** * Submits a code form by clicking the button with method=code */ submitCodeForm(app: "mobile" | "express" | "react"): Chainable /** * Expect a CSRF error to occur * * @param opts */ shouldHaveCsrfError(opts: { app: string }): Chainable /** * Expects the app to error if a return_to is used which isn't allowed. * * @param init * @param opts */ shouldErrorOnDisallowedReturnTo( init: string, opts: { app: string }, ): Chainable /** * Expect that the second factor login screen is shown */ shouldShow2FAScreen(): Chainable /** Click a webauthn button * * @param type */ clickWebAuthButton(type: "login" | "register"): Chainable /** * Sign up a user using Social Sign In * * @param opts */ registerOidc(opts: { app: app email?: string website?: string scopes?: Array rememberLogin?: boolean rememberConsent?: boolean acceptLogin?: boolean acceptConsent?: boolean expectSession?: boolean route?: string }): Chainable /** * Sign in a user using Social Sign In * * @param opts */ loginOidc(opts: { app: app expectSession?: boolean url?: string preTriggerHook?: () => void }): Chainable /** * Triggers a Social Sign In flow for the given provider * * @param app * @param provider */ triggerOidc(app: "react" | "express", provider?: string): Chainable /** * Changes the config so that the recovery privileged lifespan is very long. * * Useful when testing privileged recovery flows. * * @see shortPrivilegedRecoveryTime() */ longRecoveryLifespan(): Chainable /** * Changes the config so that the recovery privileged lifespan is very short. * * Useful when testing privileged recovery flows. * * @see shortPrivilegedRecoveryTime() */ shortRecoveryLifespan(): Chainable /** * Changes the config so that the verification privileged lifespan is very long. * * Useful when testing recovery/verification flows. * * @see shortLinkLifespan() */ longVerificationLifespan(): Chainable /** * Changes the config so that the verification privileged lifespan is very short. * * Useful when testing privileged verification flows. * * @see shortPrivilegedVerificationTime() */ shortVerificationLifespan(): Chainable /** * Log a user out */ logout(): Chainable /** * Deletes all mail in the mail mock server. * * @param opts */ deleteMail(opts?: { atLeast?: number }): Chainable /** * Changes the config so that the link lifespan is very long. * * Useful when testing recovery/verification flows. * * @see shortLinkLifespan() */ longLinkLifespan(): Chainable /** * Changes the config so that the link lifespan is very short. * * Useful when testing recovery/verification flows. * * @see longLinkLifespan() */ shortLinkLifespan(): Chainable /** * Changes the config so that the code lifespan is very short. * * Useful when testing recovery/verification flows. * * @see longCodeLifespan() */ shortCodeLifespan(): Chainable /** * Sets the `lifespan` of a strategy to 1ms (a short value) * * Useful to test the behavior if the subject of the strategy expired * * @param s the strategy */ shortLifespan(s: Strategy): Chainable /** * Sets the `lifespan` of a strategy to 1m * * @param s the strategy */ longLifespan(s: Strategy): Chainable /** * Changes the config so that the code lifespan is very long. * * Useful when testing recovery/verification flows. * * @see shortCodeLifespan() */ longCodeLifespan(): Chainable /** * Expect a recovery email which is expired. * * @param opts */ recoverEmailButExpired(opts?: { expect: { email: string } }): Chainable /** * Expect a recovery email with a recovery code. * * @param opts */ recoveryEmailWithCode(opts?: { expect: { email: string; enterCode?: boolean } }): Chainable /** * Expect a verification email which is expired. * * @param opts */ verifyEmailButExpired(opts?: { expect: { email: string } strategy?: Strategy }): Chainable /** * Disables verification */ disableVerification(): Chainable /** * Enables verification */ enableVerification(): Chainable /** * Enables recovery */ enableRecovery(): Chainable /** * Sets the recovery strategy to use */ useRecoveryStrategy(strategy: Strategy): Chainable /** * Disables a specific recovery strategy * * @param strategy the recovery strategy to disable */ disableRecoveryStrategy(strategy: Strategy): Chainable /** * Disabled recovery */ disableRecovery(): Chainable /** * Disables registration */ disableRegistration(): Chainable /** * Enables registration */ enableRegistration(): Chainable /** * Expect a recovery email which is valid. * * @param opts */ recoverEmail(opts: { expect: { email: string } shouldVisit?: boolean }): Chainable /** * Expect a verification email which is valid. * * @param opts */ verifyEmail(opts: { expect: { email: string; password?: string; redirectTo?: string } strategy?: Strategy shouldVisit?: boolean }): Chainable /** * Configures a hook which only allows verified email addresses to sign in. */ enableLoginForVerifiedAddressOnly(): Chainable /** * Sets the value for the `notify_unknown_recipients` key for a flow * * @param flow the flow for which to set the config value * @param value the value, defaults to true */ notifyUnknownRecipients( flow: "recovery" | "verification", value?: boolean, ): Chainable /** * Sign a user in via the API and return the session. * * @param opts */ loginApi(opts: { email: string password: string }): Chainable<{ session: KratosSession }> /** * Same as loginApi but uses dark magic to avoid cookie issues. * * @param opts */ loginApiWithoutCookies(opts: { email: string password: string }): Chainable<{ session: KratosSession }> /** * Which app to proxy */ proxy(app: "react" | "express"): Chainable /** * Log a user in on mobile * * @param opts */ loginMobile(opts: { email: string; password: string }): Chainable /** * Set the identity schema * @param schema */ setIdentitySchema(schema: string): Chainable /** * Set the default schema * @param id */ setDefaultIdentitySchema(id: string): Chainable /** * Remove the specified attribute from the given HTML elements */ removeAttribute(selectors: string[], attribute: string): Chainable /** * Add an input element to the DOM as a child of the given parent */ addInputElement( parent: string, attribute: string, value: string, ): Chainable /** * Fetches the courier messages from the admin API */ getCourierMessages(): Chainable< { recipient: string; template_type: string }[] > /** * Enable the verification UI after registration hook */ enableVerificationUIAfterRegistration( strategy: "password" | "oidc" | "webauthn", ): Chainable /** * Extracts a verification code from the received email */ getVerificationCodeFromEmail(email: string): Chainable /** * Extracts a registration code from the received email */ getRegistrationCodeFromEmail( email: string, opts?: { expectedCount: number; removeMail?: boolean }, ): Chainable /** * Extracts a login code from the received email */ getLoginCodeFromEmail( email: string, opts?: { expectedCount: number }, ): Chainable useConfig(cb: (config: ConfigBuilder) => ConfigBuilder): Chainable } } }