diff --git a/e2e/davinci-app/components/object-value.ts b/e2e/davinci-app/components/object-value.ts index e5c4459565..cf025d022e 100644 --- a/e2e/davinci-app/components/object-value.ts +++ b/e2e/davinci-app/components/object-value.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -75,33 +75,64 @@ export default function objectValueComponent( phoneLabel.className = 'object-options-title'; phoneLabel.setAttribute('for', 'phone-number-input'); + // Country code dropdown + const countryCodeLabel = document.createElement('label'); + countryCodeLabel.textContent = 'Country Code'; + countryCodeLabel.setAttribute('for', collector.output.key || 'dropdown-field'); + countryCodeLabel.className = 'dropdown-label'; + countryCodeLabel.setAttribute('for', collector.output.key || 'dropdown-field'); + + const countryCodeInput = document.createElement('select'); + countryCodeInput.name = collector.output.key || 'dropdown-field'; + countryCodeInput.id = collector.output.key || 'dropdown-field'; + + const countryCodes = ['IN', 'BR', 'CA', 'US']; + for (const option of countryCodes) { + const optionEl = document.createElement('option'); + optionEl.value = option; + optionEl.textContent = option; + countryCodeInput.appendChild(optionEl); + } + + // Phone number input const phoneInput = document.createElement('input'); phoneInput.setAttribute('type', 'tel'); phoneInput.setAttribute('id', 'phone-number-input'); phoneInput.setAttribute('name', 'phone-number-input'); phoneInput.setAttribute('placeholder', 'Enter phone number'); + formEl.appendChild(countryCodeLabel); + formEl.appendChild(countryCodeInput); formEl.appendChild(phoneLabel); formEl.appendChild(phoneInput); - // Add change event listener + const phoneNumberUpdater = updater as Updater; + + // Add change event listener for phone number input phoneInput.addEventListener('change', (event) => { - // Properly type the event target const target = event.target as HTMLInputElement; - const selectedValue = target.value; - - if (!selectedValue) { - console.error('No value found for the selected option'); - return; - } - + const phoneValue = target.value; + const countryCodeValue = countryCodeInput.value; const phoneNumberInputValue: PhoneNumberInputValue = { - phoneNumber: selectedValue, - countryCode: collector.output.value?.countryCode || '', + phoneNumber: phoneValue, + countryCode: countryCodeValue || collector.output.value?.countryCode || '', }; - const phoneNumberUpdater = updater as Updater; + phoneNumberUpdater(phoneNumberInputValue); }); + + // Add change event listener for extension input + countryCodeInput.addEventListener('change', (event) => { + const target = event.target as HTMLSelectElement; + const countryCodeValue = target.value; + const phoneValue = phoneInput.value; + const countryCodeInputValue: PhoneNumberInputValue = { + phoneNumber: phoneValue, + countryCode: countryCodeValue || collector.output.value?.countryCode || '', + }; + + phoneNumberUpdater(countryCodeInputValue); + }); } else if (collector.type === 'PhoneNumberExtensionCollector') { const phoneLabel = document.createElement('label'); phoneLabel.textContent = collector.output.label || 'Phone Number'; diff --git a/e2e/davinci-app/main.ts b/e2e/davinci-app/main.ts index 2bf7754292..72055d8eb6 100644 --- a/e2e/davinci-app/main.ts +++ b/e2e/davinci-app/main.ts @@ -59,7 +59,7 @@ const qs = window.location.search; const searchParams = new URLSearchParams(qs); const config: DaVinciConfig = - serverConfigs[searchParams.get('clientId') || '724ec718-c41c-4d51-98b0-84a583f450f9']; + serverConfigs[searchParams.get('clientId') || '625e45e0-dde5-402e-9bf9-7da1275df03a']; const logger: { level: 'debug'; custom?: typeof loggerFn } = { level: 'debug' as const, diff --git a/e2e/davinci-app/server-configs.ts b/e2e/davinci-app/server-configs.ts index c41dda42a5..7a33887db2 100644 --- a/e2e/davinci-app/server-configs.ts +++ b/e2e/davinci-app/server-configs.ts @@ -34,32 +34,20 @@ export const serverConfigs: Record = { }, }, /** - * SDK Team Tenant - * DemoUser-sdkWebClient + * Login Registration */ - '724ec718-c41c-4d51-98b0-84a583f450f9': { - clientId: '724ec718-c41c-4d51-98b0-84a583f450f9', + '625e45e0-dde5-402e-9bf9-7da1275df03a': { + clientId: '625e45e0-dde5-402e-9bf9-7da1275df03a', redirectUri: window.location.origin + '/', scope: 'openid profile email name revoke', serverConfig: { wellknown: - 'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration', - }, - }, - /** - * Form Fields (old env — image feature flag enabled) - */ - '60de77d5-dd2c-41ef-8c40-f8bb2381a359': { - clientId: '60de77d5-dd2c-41ef-8c40-f8bb2381a359', - redirectUri: window.location.origin + '/', - scope: 'openid profile email name revoke', - serverConfig: { - wellknown: - 'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration', + 'https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/.well-known/openid-configuration', }, }, /** * Form Fields + * QR Code * ValidatedPasswordCollector / Password Policy */ 'e4ef2896-8d90-4abd-bf0f-7b8034995927': { @@ -72,29 +60,19 @@ export const serverConfigs: Record = { }, }, /** - * Phone Number Input With Email and Password + * MFA: FIDO, Email, SMS */ - '20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0': { - clientId: '20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0', + '9c1d9655-7d1b-46f3-a96d-345690259d2a': { + clientId: '9c1d9655-7d1b-46f3-a96d-345690259d2a', redirectUri: window.location.origin + '/', scope: 'openid profile email revoke', serverConfig: { wellknown: - 'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration', - }, - }, - /** QR Code policy id : aa3c00c3ec25a9721be078f7bf44678d **/ - 'c12743f9-08e8-4420-a624-71bbb08e9fe1': { - clientId: 'c12743f9-08e8-4420-a624-71bbb08e9fe1', - redirectUri: window.location.origin + '/', - scope: 'openid profile email', - serverConfig: { - wellknown: - 'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration', + 'https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/.well-known/openid-configuration', }, }, /** - * AutoCollectors: Polling, Metadata, FIDO, Protect + * AutoCollectors: Polling, Metadata, Protect */ '31a587ce-9aa4-4f36-a09f-78cd8a0a74a0': { clientId: '31a587ce-9aa4-4f36-a09f-78cd8a0a74a0', diff --git a/e2e/davinci-suites/src/basic.test.ts b/e2e/davinci-suites/src/basic.test.ts index 43002ae465..56db4f3994 100644 --- a/e2e/davinci-suites/src/basic.test.ts +++ b/e2e/davinci-suites/src/basic.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -39,6 +39,7 @@ test('Test happy paths on test page', async ({ page }) => { if (response.url().includes('/revoke') && response.status() === 200) { return true; } + return false; }); await logoutButton.click(); await revokeCall; @@ -50,7 +51,7 @@ test('ensure query params passed to start are sent off in authorize call', async const requestPromise = page.waitForRequest((request) => { return request .url() - .includes('https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/authorize'); + .includes('https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/authorize'); }); await navigate('/?testParam=123'); @@ -62,7 +63,7 @@ test('ensure query params passed to start are sent off in authorize call', async const queryParams = Object.fromEntries(url.searchParams.entries()); expect(queryParams['testParam']).toBe('123'); - expect(queryParams['client_id']).toBe('724ec718-c41c-4d51-98b0-84a583f450f9'); + expect(queryParams['client_id']).toBe('625e45e0-dde5-402e-9bf9-7da1275df03a'); expect(queryParams['response_mode']).toBe('pi.flow'); expect(page.url()).toBe('http://localhost:5829/?testParam=123'); diff --git a/e2e/davinci-suites/src/fido.test.ts b/e2e/davinci-suites/src/fido.test.ts index b5e73c1504..0047498079 100644 --- a/e2e/davinci-suites/src/fido.test.ts +++ b/e2e/davinci-suites/src/fido.test.ts @@ -10,8 +10,8 @@ import { asyncEvents } from './utils/async-events.js'; const username = 'JSFidoUser@user.com'; const password = 'FakePassword#123'; -const clientId = '31a587ce-9aa4-4f36-a09f-78cd8a0a74a0'; -const policyId = '3eff62cf953372519225d375fd200358'; +const clientId = '9c1d9655-7d1b-46f3-a96d-345690259d2a'; +const policyId = '4b6008f10ba174dd3ce3ab60c5b81d7e'; test.use({ browserName: 'chromium' }); // ensure CDP/WebAuthn is available test.describe.configure({ mode: 'serial' }); diff --git a/e2e/davinci-suites/src/form-image.test.ts b/e2e/davinci-suites/src/form-image.test.ts index 72a2810c99..2ce11a2dd3 100644 --- a/e2e/davinci-suites/src/form-image.test.ts +++ b/e2e/davinci-suites/src/form-image.test.ts @@ -10,9 +10,9 @@ import { asyncEvents } from './utils/async-events.js'; test('Should render image collector in form', async ({ page }) => { const { navigate } = asyncEvents(page); - await navigate('/?clientId=60de77d5-dd2c-41ef-8c40-f8bb2381a359'); + await navigate('/?clientId=e4ef2896-8d90-4abd-bf0f-7b8034995927'); - await expect(page.getByText('Select Test Form')).toBeVisible(); + await expect(page.getByText('Select Form Fields Test Form')).toBeVisible(); await page.getByRole('button', { name: 'Form Fields' }).click(); await expect(page.getByText('Form Fields Tests')).toBeVisible(); diff --git a/e2e/davinci-suites/src/middleware.test.ts b/e2e/davinci-suites/src/middleware.test.ts index eeb8709551..712e098ae4 100644 --- a/e2e/davinci-suites/src/middleware.test.ts +++ b/e2e/davinci-suites/src/middleware.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -9,7 +9,7 @@ import { asyncEvents } from './utils/async-events.js'; import { password, username } from './utils/demo-user.js'; test('Test middleware on test page', async ({ page }) => { - const networkArray = []; + const networkArray: { url: string; langHeader: string | null }[] = []; page.on('request', async (req) => { const url = req.url().toString(); const langHeader = await req.headerValue('Accept-Language'); @@ -36,14 +36,14 @@ test('Test middleware on test page', async ({ page }) => { const nextRequest = networkArray.find((req) => req.url.includes('/customHTMLTemplate')); // Check for addition of query params - await expect(startRequest.url.includes('start=true')).toBeTruthy(); - await expect(startRequest.url.includes('next=true')).toBeFalsy(); - await expect(nextRequest.url.includes('next=true')).toBeTruthy(); - await expect(nextRequest.url.includes('start=true')).toBeFalsy(); + await expect(startRequest?.url.includes('start=true')).toBeTruthy(); + await expect(startRequest?.url.includes('next=true')).toBeFalsy(); + await expect(nextRequest?.url.includes('next=true')).toBeTruthy(); + await expect(nextRequest?.url.includes('start=true')).toBeFalsy(); // Check that Accept-Language header was modified from default en-US locale - await expect(startRequest.langHeader).not.toContain('en-US'); - await expect(startRequest.langHeader).toBe('xx-XX'); - await expect(nextRequest.langHeader).not.toContain('en-US'); - await expect(nextRequest.langHeader).toBe('zz-ZZ'); + await expect(startRequest?.langHeader).not.toContain('en-US'); + await expect(startRequest?.langHeader).toBe('xx-XX'); + await expect(nextRequest?.langHeader).not.toContain('en-US'); + await expect(nextRequest?.langHeader).toBe('zz-ZZ'); }); diff --git a/e2e/davinci-suites/src/password-policy.test.ts b/e2e/davinci-suites/src/password-policy.test.ts index a223d0124b..555a53ef0c 100644 --- a/e2e/davinci-suites/src/password-policy.test.ts +++ b/e2e/davinci-suites/src/password-policy.test.ts @@ -9,7 +9,7 @@ import { asyncEvents } from './utils/async-events.js'; import { password } from './utils/demo-user.js'; const CLIENT_ID = 'e4ef2896-8d90-4abd-bf0f-7b8034995927'; -const POLICY_ID = '5e8613e337c67a67db09373019e962e0'; +const POLICY_ID = '93d0e640dcf435ffc458228bca04be5f'; /** * A unique email per test run to avoid conflicts with existing accounts. diff --git a/e2e/davinci-suites/src/phone-number-field.test.ts b/e2e/davinci-suites/src/phone-number-field.test.ts index fc1017adb3..97a5265a8e 100644 --- a/e2e/davinci-suites/src/phone-number-field.test.ts +++ b/e2e/davinci-suites/src/phone-number-field.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -9,9 +9,11 @@ import { password } from './utils/demo-user.js'; test.describe('Device registration tests', () => { const username = 'fakeemail@user.com'; + const clientId = '9c1d9655-7d1b-46f3-a96d-345690259d2a'; + const policyId = '4b6008f10ba174dd3ce3ab60c5b81d7e'; test.afterEach(async ({ page }) => { - await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0'); + await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`); await page.getByRole('button', { name: 'USER_LOGIN' }).click(); await page.getByRole('textbox', { name: 'Username' }).fill(username); @@ -24,22 +26,23 @@ test.describe('Device registration tests', () => { test('Login - add email device - authenticate with email device', async ({ page }) => { /** Go to page */ - await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0'); + await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`); expect(page.url()).toContain( - 'http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0', + `http://localhost:5829/?clientId=${clientId}&acr_values=${policyId}`, ); - await expect(page.getByText('Select Test Form')).toBeVisible(); + await expect(page.getByText('FIDO2 Test Form')).toBeVisible(); /** * Register a new user */ await page.getByRole('button', { name: 'USER_REGISTRATION' }).click(); - await page.getByRole('textbox', { name: 'Email' }).fill(username); + + await page.getByRole('textbox', { name: 'Username' }).fill(username); + await page.getByRole('textbox', { name: 'Email Address' }).fill(username); await page.getByRole('textbox', { name: 'Password' }).fill(password); - await page.getByRole('textbox', { name: 'Given Name' }).fill('demouser'); - await page.getByRole('textbox', { name: 'Family Name' }).fill('demouser'); - await page.getByRole('button', { name: 'Continue' }).click(); + await page.getByRole('button', { name: 'Submit' }).click(); + await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible(); await page.getByRole('button', { name: 'Continue' }).click(); await page.getByRole('button', { name: 'Logout' }).click(); @@ -47,7 +50,7 @@ test.describe('Device registration tests', () => { /*** * Login with the new user **/ - await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0'); + await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`); await page.getByRole('button', { name: 'USER_LOGIN' }).click(); await expect(page.getByText('SDK Automation - Sign On')).toBeVisible(); await page.getByRole('textbox', { name: 'Username' }).fill(username); @@ -55,9 +58,9 @@ test.describe('Device registration tests', () => { await page.getByRole('button', { name: 'Sign On' }).click(); /** Register a device */ - await expect(page.getByText('Select Test Form')).toBeVisible(); + await expect(page.getByText('FIDO2 Test Form')).toBeVisible(); await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click(); - await expect(page.getByText('SDK Automation - Device Registration')).toBeVisible(); + await expect(page.getByText('MFA Device Selection - Registration')).toBeVisible(); await page.getByRole('button', { name: 'Email' }).click(); await page .getByRole('textbox', { name: 'Email Address' }) @@ -69,21 +72,21 @@ test.describe('Device registration tests', () => { test('Login - add phone device - authenticate with phone device', async ({ page }) => { /** Go to page */ - await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0'); + await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`); expect(page.url()).toContain( - 'http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0', + `http://localhost:5829/?clientId=${clientId}&acr_values=${policyId}`, ); /** * Register a new user **/ - await expect(page.getByText('Select Test Form')).toBeVisible(); + await expect(page.getByText('FIDO2 Test Form')).toBeVisible(); await page.getByRole('button', { name: 'USER_REGISTRATION' }).click(); - await page.getByRole('textbox', { name: 'Email' }).fill(username); + await page.getByRole('textbox', { name: 'Username' }).fill(username); + await page.getByRole('textbox', { name: 'Email Address' }).fill(username); await page.getByRole('textbox', { name: 'Password' }).fill(password); - await page.getByRole('textbox', { name: 'Given Name' }).fill('demouser'); - await page.getByRole('textbox', { name: 'Family Name' }).fill('demouser'); - await page.getByRole('button', { name: 'Continue' }).click(); + await page.getByRole('button', { name: 'Submit' }).click(); + await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible(); await page.getByRole('button', { name: 'Continue' }).click(); await page.getByRole('button', { name: 'Logout' }).click(); @@ -91,7 +94,7 @@ test.describe('Device registration tests', () => { /** * Login with the new user **/ - await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0'); + await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`); await page.getByRole('button', { name: 'USER_LOGIN' }).click(); await expect(page.getByText('SDK Automation - Sign On')).toBeVisible(); await page.getByRole('textbox', { name: 'Username' }).fill(username); @@ -99,11 +102,12 @@ test.describe('Device registration tests', () => { await page.getByRole('button', { name: 'Sign On' }).click(); /** Register a Device */ - await expect(page.getByText('Select Test Form')).toBeVisible(); + await expect(page.getByText('FIDO2 Test Form')).toBeVisible(); await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click(); - await expect(page.getByText('SDK Automation - Device Registration')).toBeVisible(); + await expect(page.getByText('MFA Device Selection - Registration')).toBeVisible(); await page.getByRole('button', { name: 'Text Message' }).click(); - await expect(page.getByText('SDK Automation [JS] - Enter Phone Number')).toBeVisible(); + await expect(page.getByText('SDK Automation - Standard Phone Number')).toBeVisible(); + await page.getByLabel('Country Code').selectOption('US'); await page.getByRole('textbox', { name: 'Enter Phone Number' }).fill('3035550100'); await expect(page.getByText('Extension')).not.toBeVisible(); // Tests standard PhoneNumberCollector await page.getByRole('button', { name: 'Submit' }).click(); diff --git a/e2e/davinci-suites/src/qr-code.test.ts b/e2e/davinci-suites/src/qr-code.test.ts index b68d157f6d..63d37b5ce4 100644 --- a/e2e/davinci-suites/src/qr-code.test.ts +++ b/e2e/davinci-suites/src/qr-code.test.ts @@ -1,39 +1,21 @@ /* - * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ import { expect, test } from '@playwright/test'; import { asyncEvents } from './utils/async-events.js'; -import { password, username } from './utils/demo-user.js'; -const qrCodeUrl = - '/?clientId=c12743f9-08e8-4420-a624-71bbb08e9fe1&acr_values=9da1b93991bcd577947da228ad4c741f'; +const clientId = 'e4ef2896-8d90-4abd-bf0f-7b8034995927'; +const policyId = 'b6c0b61b1c7697f9fcfb013d05e8f977'; +const qrCodeUrl = `/?clientId=${clientId}&acr_values=${policyId}`; -test('QR code renders after navigating through device registration flow', async ({ page }) => { +test('QR code renders on screen', async ({ page }) => { const { navigate } = asyncEvents(page); await navigate(qrCodeUrl); - // Step 1: Login - await page.getByRole('button', { name: 'USER_LOGIN' }).click(); - await page.waitForEvent('requestfinished'); - - await page.getByLabel('Username').fill(username); - await page.getByLabel('Password').fill(password); - await page.getByRole('button', { name: 'Sign On' }).click(); - await page.waitForEvent('requestfinished'); - - // Step 2: Select device registration - await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click(); - await page.waitForEvent('requestfinished'); - - // Step 3: Choose "Mobile App" from the device selection screen - await expect(page.getByText('MFA Device Selection - Registration')).toBeVisible(); - await page.getByRole('button', { name: 'Mobile App' }).click(); - await page.waitForEvent('requestfinished'); - // Step 4: QR code should now be visible const qrImage = page.locator('[data-testid="qr-code-image"]'); await expect(qrImage).toBeVisible({ timeout: 10000 }); diff --git a/e2e/oidc-app/src/ping-one/main.ts b/e2e/oidc-app/src/ping-one/main.ts index d0c5de5569..2e60a93e74 100644 --- a/e2e/oidc-app/src/ping-one/main.ts +++ b/e2e/oidc-app/src/ping-one/main.ts @@ -1,6 +1,6 @@ /* * - * Copyright © 2025 Ping Identity Corporation. All right reserved. + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -13,13 +13,13 @@ const clientId = urlParams.get('clientid'); const wellknown = urlParams.get('wellknown'); const config = { - clientId: clientId || '654b14e2-7cc5-4977-8104-c4113e43c537', + clientId: clientId || '00e62f85-3d49-4046-b860-15aefdebbb0d', redirectUri: 'http://localhost:8443/ping-one/', scope: 'openid revoke profile email', serverConfig: { wellknown: wellknown || - 'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration', + 'https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/.well-known/openid-configuration', }, };