33 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44
55import { expect , test } from '../../lib/fixtures/standard' ;
6- import { relayDesktopOAuthQueryParams , syncDesktopOAuthQueryParams } from '../../lib/query-params' ;
6+ import {
7+ relayDesktopOAuthQueryParams ,
8+ syncDesktopOAuthQueryParams ,
9+ } from '../../lib/query-params' ;
710import { getTotpCode } from '../../lib/totp' ;
811
912test . describe ( 'severity-1 #smoke' , ( ) => {
@@ -344,11 +347,7 @@ test.describe('severity-1 #smoke', () => {
344347 expect ( Array . isArray ( events ) ) . toBe ( true ) ;
345348
346349 // Cleanup
347- await target . authClient . createPassword (
348- sessionToken ,
349- email ,
350- password
351- ) ;
350+ await target . authClient . createPassword ( sessionToken , email , password ) ;
352351 account . isPasswordless = false ;
353352 } ) ;
354353 } ) ;
@@ -480,10 +479,7 @@ test.describe('severity-1 #smoke', () => {
480479
481480 // Verify TOTP
482481 const totpCode = await getTotpCode ( secret ) ;
483- await target . authClient . verifyTotpCode (
484- result . sessionToken ,
485- totpCode
486- ) ;
482+ await target . authClient . verifyTotpCode ( result . sessionToken , totpCode ) ;
487483
488484 // Confirm verified after TOTP
489485 const statusAfter = await target . authClient . sessionStatus (
@@ -701,12 +697,11 @@ test.describe('severity-1 #smoke', () => {
701697 } ) ;
702698 const cleanupCode =
703699 await target . emailClient . getPasswordlessSigninCode ( email ) ;
704- const cleanupResult =
705- await target . authClient . passwordlessConfirmCode (
706- email ,
707- cleanupCode ,
708- { clientId : 'dcdb5ae7add825d2' }
709- ) ;
700+ const cleanupResult = await target . authClient . passwordlessConfirmCode (
701+ email ,
702+ cleanupCode ,
703+ { clientId : 'dcdb5ae7add825d2' }
704+ ) ;
710705 // Elevate to AAL2 for password creation
711706 const cleanupTotpCode = await getTotpCode ( secret ) ;
712707 await target . authClient . verifyTotpCode (
@@ -735,8 +730,7 @@ test.describe('severity-2', () => {
735730 pages : { page, signin, relier, signinPasswordlessCode } ,
736731 testAccountTracker,
737732 } ) => {
738- const { email } =
739- testAccountTracker . generatePasswordlessAccountDetails ( ) ;
733+ const { email } = testAccountTracker . generatePasswordlessAccountDetails ( ) ;
740734
741735 await relier . goto ( 'force_passwordless=true' ) ;
742736 await relier . clickEmailFirst ( ) ;
@@ -761,8 +755,7 @@ test.describe('severity-2', () => {
761755 pages : { page, signin, relier, signinPasswordlessCode } ,
762756 testAccountTracker,
763757 } ) => {
764- const { email } =
765- testAccountTracker . generatePasswordlessAccountDetails ( ) ;
758+ const { email } = testAccountTracker . generatePasswordlessAccountDetails ( ) ;
766759
767760 await relier . goto ( 'force_passwordless=true' ) ;
768761 await relier . clickEmailFirst ( ) ;
@@ -781,9 +774,7 @@ test.describe('severity-2', () => {
781774 await expect ( signin . cachedSigninHeading ) . toBeVisible ( ) ;
782775
783776 // Navigate to /signin directly — same behavior
784- await page . goto (
785- `${ target . contentServerUrl } /signin?email=${ email } `
786- ) ;
777+ await page . goto ( `${ target . contentServerUrl } /signin?email=${ email } ` ) ;
787778 await expect ( page ) . not . toHaveURL ( / s i g n i n _ p a s s w o r d l e s s _ c o d e / ) ;
788779 await expect ( signin . cachedSigninHeading ) . toBeVisible ( ) ;
789780 } ) ;
@@ -793,12 +784,9 @@ test.describe('severity-2', () => {
793784 pages : { page, signin, signinPasswordlessCode, settings } ,
794785 testAccountTracker,
795786 } ) => {
796- const { email } =
797- testAccountTracker . generatePasswordlessAccountDetails ( ) ;
787+ const { email } = testAccountTracker . generatePasswordlessAccountDetails ( ) ;
798788
799- await page . goto (
800- `${ target . contentServerUrl } /?force_passwordless=true`
801- ) ;
789+ await page . goto ( `${ target . contentServerUrl } /?force_passwordless=true` ) ;
802790 await signin . fillOutEmailFirstForm ( email ) ;
803791
804792 await expect ( page ) . toHaveURL ( / s i g n i n _ p a s s w o r d l e s s _ c o d e / ) ;
@@ -886,14 +874,17 @@ test.describe('severity-2', () => {
886874 await target . authClient . passwordlessSendCode ( email , {
887875 clientId : 'dcdb5ae7add825d2' ,
888876 } ) ;
889- const otpCode =
890- await target . emailClient . getPasswordlessSigninCode ( email ) ;
877+ const otpCode = await target . emailClient . getPasswordlessSigninCode ( email ) ;
891878 const result = await target . authClient . passwordlessConfirmCode (
892879 email ,
893880 otpCode ,
894881 { clientId : 'dcdb5ae7add825d2' }
895882 ) ;
896- await target . authClient . createPassword ( result . sessionToken , email , password ) ;
883+ await target . authClient . createPassword (
884+ result . sessionToken ,
885+ email ,
886+ password
887+ ) ;
897888 account . isPasswordless = false ;
898889
899890 // First account now has a password — should show password form
@@ -920,11 +911,7 @@ test.describe('severity-2', () => {
920911
921912 test ( 'passwordless signin - Sync with existing passwordless account' , async ( {
922913 target,
923- syncOAuthBrowserPages : {
924- page,
925- signin,
926- signinPasswordlessCode,
927- } ,
914+ syncOAuthBrowserPages : { page, signin, signinPasswordlessCode } ,
928915 testAccountTracker,
929916 } ) => {
930917 // Create passwordless account via API first (no password)
@@ -1039,7 +1026,7 @@ test.describe('severity-2', () => {
10391026 } ) ;
10401027 } ) ;
10411028
1042- test . describe ( 'Passwordless authentication - Browser Service (Relay)' , ( ) => {
1029+ test . describe ( 'Passwordless authentication - Browser Service (Relay)' , ( ) => {
10431030 test ( 'passwordless signin via Relay OAuth flow' , async ( {
10441031 target,
10451032 pages : { page, signin, signinPasswordlessCode } ,
@@ -1062,5 +1049,53 @@ test.describe('Passwordless authentication - Browser Service (Relay)', () => {
10621049 // completes the OAuth flow — verify we left the OTP page
10631050 await expect ( page ) . not . toHaveURL ( / s i g n i n _ p a s s w o r d l e s s _ c o d e / ) ;
10641051 } ) ;
1065- } ) ;
1066- } ) ;
1052+
1053+ test ( 'passwordless signup via Relay OAuth flow - service allowed' , async ( {
1054+ target,
1055+ pages : { page, signin, signinPasswordlessCode } ,
1056+ testAccountTracker,
1057+ } ) => {
1058+ // Test that Relay (which is in allowedClientServices) supports passwordless signup
1059+ const { email } = testAccountTracker . generatePasswordlessAccountDetails ( ) ;
1060+
1061+ const params = new URLSearchParams ( relayDesktopOAuthQueryParams ) ;
1062+ // Add force_passwordless to enable passwordless for new account
1063+ params . set ( 'force_passwordless' , 'true' ) ;
1064+ await signin . goto ( '/authorization' , params ) ;
1065+
1066+ await signin . fillOutEmailFirstForm ( email ) ;
1067+
1068+ // Should redirect to passwordless code page (Relay service is allowed)
1069+ await expect ( page ) . toHaveURL ( / s i g n i n _ p a s s w o r d l e s s _ c o d e / ) ;
1070+ await expect ( signinPasswordlessCode . heading ) . toBeVisible ( ) ;
1071+
1072+ const code = await target . emailClient . getPasswordlessSignupCode ( email ) ;
1073+ await signinPasswordlessCode . fillOutCodeForm ( code ) ;
1074+
1075+ // Should complete OAuth flow
1076+ await expect ( page ) . not . toHaveURL ( / s i g n i n _ p a s s w o r d l e s s _ c o d e / ) ;
1077+ } ) ;
1078+
1079+ test ( 'passwordless signup blocked for service not in allowedClientServices' , async ( {
1080+ target,
1081+ pages : { page, signin } ,
1082+ testAccountTracker,
1083+ } ) => {
1084+ // Test that services NOT in allowedClientServices are blocked from passwordless
1085+ const { email } = testAccountTracker . generatePasswordlessAccountDetails ( ) ;
1086+
1087+ // Use a different OAuth client that is NOT in allowedClientServices
1088+ // (using Sync client as an example of a service that doesn't support passwordless signup)
1089+ const params = new URLSearchParams ( syncDesktopOAuthQueryParams ) ;
1090+ params . set ( 'force_passwordless' , 'true' ) ;
1091+ await signin . goto ( '/authorization' , params ) ;
1092+
1093+ await signin . fillOutEmailFirstForm ( email ) ;
1094+
1095+ // Should NOT redirect to passwordless code page
1096+ // Instead should go to traditional signup flow (password form)
1097+ await expect ( page ) . not . toHaveURL ( / s i g n i n _ p a s s w o r d l e s s _ c o d e / ) ;
1098+ await expect ( page ) . toHaveURL ( / s i g n u p / ) ;
1099+ } ) ;
1100+ } ) ;
1101+ } ) ;
0 commit comments