Files
upstream-mirror c60cc7ca75
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
2026-09-15 21:19:12 +05:00

184 lines
6.4 KiB
TypeScript

// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
import { APP_URL, gen } from "../../../helpers"
import * as oauth2 from "../../../helpers/oauth2"
import * as httpbin from "../../../helpers/httpbin"
context("OpenID Provider", () => {
before(() => {
cy.useConfigProfile("oidc-provider")
cy.proxy("express")
})
const client = {
auth_endpoint: "http://localhost:4744/oauth2/auth",
token_endpoint: "http://localhost:4744/oauth2/token",
id: Cypress.env("OIDC_DUMMY_CLIENT_ID"),
secret: Cypress.env("OIDC_DUMMY_CLIENT_SECRET"),
token_endpoint_auth_method: "client_secret_basic",
grant_types: ["authorization_code", "refresh_token"],
response_types: ["code", "id_token"],
scopes: ["openid", "offline", "email", "website"],
callbacks: [
"http://localhost:5555/callback",
"https://ory-network-httpbin-ijakee5waq-ez.a.run.app/anything",
],
}
it("registration", () => {
const url = oauth2.getDefaultAuthorizeURL(client)
cy.visit(url)
cy.get("[data-testid=signup-link]").click()
const email = gen.email()
const password = gen.password()
cy.get('[name="traits.email"]').type(email)
cy.get("[name=password]").type(password)
cy.get('[name="traits.website"]').type("http://example.com")
cy.get('input[type=checkbox][name="traits.tos"]').click({ force: true })
cy.get('[name="traits.age"]').type("199")
cy.get('input[type=checkbox][name="traits.consent"]').click({ force: true })
cy.get('input[type=checkbox][name="traits.newsletter"]').click({
force: true,
})
cy.get("[type='submit'][value='password']").click()
cy.get("#openid").click()
cy.get("#offline").click()
cy.get("#accept").click()
const scope = ["offline", "openid"]
httpbin.checkToken(client, scope, (token: any) => {
expect(token).to.have.property("access_token")
expect(token).to.have.property("id_token")
expect(token).to.have.property("refresh_token")
expect(token).to.have.property("token_type")
expect(token).to.have.property("expires_in")
expect(token.scope).to.equal("offline openid")
let idToken = JSON.parse(
decodeURIComponent(escape(window.atob(token.id_token.split(".")[1]))),
)
expect(idToken).to.have.property("amr")
expect(idToken.amr).to.deep.equal(["password"])
})
})
it("registration with session, skip=false and skip=true", () => {
const email = gen.email()
const password = gen.password()
cy.register({
email,
password,
fields: {
"traits.website": "https://www.ory.sh",
"traits.tos": "1",
"traits.age": 22,
},
})
const url = oauth2.getDefaultAuthorizeURL(client)
cy.request(url).then((res) => {
const lastResp = res.allRequestResponses[1]["Request URL"]
const login_challenge = new URL(lastResp).searchParams.get(
"login_challenge",
)
expect(login_challenge).to.not.be.null
cy.visit(
APP_URL +
"/self-service/registration/browser?login_challenge=" +
login_challenge,
)
})
cy.url().should("contain", "/login")
cy.get("[data-testid='login-flow']").should("exist")
cy.get("[data-testid='login-flow'] [name='password']").type(password)
cy.get(
"[data-testid='login-flow'] button[name='method'][value='password']",
).click()
// we want to skip the consent flow here
// so we ask to remember the user
cy.get("[name='remember']").click()
cy.get("#openid").click()
cy.get("#offline").click()
cy.get("#accept").click()
const scope = ["offline", "openid"]
httpbin.checkToken(client, scope, (token: any) => {
expect(token).to.have.property("access_token")
expect(token).to.have.property("id_token")
expect(token).to.have.property("refresh_token")
expect(token).to.have.property("token_type")
expect(token).to.have.property("expires_in")
expect(token.scope).to.equal("offline openid")
let idToken = JSON.parse(
decodeURIComponent(escape(window.atob(token.id_token.split(".")[1]))),
)
expect(idToken).to.have.property("amr")
expect(idToken.amr).to.deep.equal(["password", "password"])
})
// use the hydra origin to make a new OAuth request from it
cy.get("body")
.then((body$) => {
// Credits https://github.com/suchipi, https://github.com/cypress-io/cypress/issues/944#issuecomment-444312914
const appWindow = body$[0].ownerDocument.defaultView
const appIframe = appWindow.parent.document.querySelector("iframe")
return new Promise((resolve) => {
appIframe.onload = () => resolve(undefined)
appWindow.location.href = "http://localhost:4744/health/ready"
})
})
.then(() => {
// we don't want to redirect here since we only want the login challenge from hydra
// we reusing the challenge to navigate to the registration page
cy.request({
url: oauth2.getDefaultAuthorizeURL(client),
followRedirect: false,
})
.then((res) => {
expect(res.redirectedToUrl).to.include("login_challenge")
return new URL(res.redirectedToUrl).searchParams.get(
"login_challenge",
)
})
.then((login_challenge) => {
cy.get("body").then((body$) => {
const appWindow = body$[0].ownerDocument.defaultView
const appIframe =
appWindow.parent.document.querySelector("iframe")
return new Promise((resolve) => {
appIframe.onload = () => resolve(undefined)
appWindow.location.href =
APP_URL +
"/self-service/registration/browser?login_challenge=" +
login_challenge
})
})
})
})
httpbin.checkToken(client, scope, (token: any) => {
expect(token).to.have.property("access_token")
expect(token).to.have.property("id_token")
expect(token).to.have.property("refresh_token")
expect(token).to.have.property("token_type")
expect(token).to.have.property("expires_in")
expect(token.scope).to.equal("offline openid")
let idToken = JSON.parse(
decodeURIComponent(escape(window.atob(token.id_token.split(".")[1]))),
)
expect(idToken).to.have.property("amr")
expect(idToken.amr).to.deep.equal(["password", "password"])
})
})
})