@@ -11,41 +11,49 @@ var qs = (function (a) {
1111
1212$ ( document ) . ready ( function ( ) {
1313 window . history . forward ( ) ;
14+ let formAction = qs [ "formAction" ] || "#" ;
15+ const opt1 = 'https://auth.{{DOMAIN}}/continue' ;
16+ const opt2 = 'https://{{AUTH0DOMAIN}}/continue' ;
17+ if ( ! formAction . startsWith ( opt1 ) && ! formAction . startsWith ( opt2 ) ) {
18+ // looks like XSS attack
19+ formAction = "#"
20+ return false ;
21+ }
1422 const resendToken = qs [ "resendToken" ] ;
1523 const userId = qs [ "userId" ] ;
1624 if ( resendToken && userId ) {
17- const apiServerUrl = "https://api.{{DOMAIN}}/v3/users" ;
18- $ ( "#resend" ) . click ( function ( ) {
19- $ . ajax ( {
20- type : "POST" ,
21- url : apiServerUrl + "/resendOtpEmail" ,
22- contentType : "application/json" ,
23- mimeType : "application/json" ,
24- data : JSON . stringify ( {
25- "param" : {
26- userId, resendToken
27- }
28- } ) ,
29- dataType : "json" ,
30- success : function ( result ) {
31- $ ( "#notify" ) . html ( "Email sent" ) ;
32- $ ( "#notify" ) . closest ( ".message-wrapper" ) . fadeIn ( ) ;
33- $ ( "#resend" ) . hide ( ) ;
34- } ,
35- error : function ( error ) {
36- if ( error . responseJSON && error . responseJSON . result ) {
37- $ ( "#error" ) . html ( error . responseJSON . result . content ) ;
38- $ ( "#error" ) . closest ( ".message-wrapper" ) . fadeIn ( ) ;
39- $ ( "#resend" ) . hide ( ) ;
40- } else {
41- $ ( "#error" ) . html ( "Unknown Error" ) ;
42- $ ( "#error" ) . closest ( ".message-wrapper" ) . fadeIn ( ) ;
43- }
44- }
45- } ) ;
25+ const apiServerUrl = "https://api.{{DOMAIN}}/v3/users" ;
26+ $ ( "#resend" ) . click ( function ( ) {
27+ $ . ajax ( {
28+ type : "POST" ,
29+ url : apiServerUrl + "/resendOtpEmail" ,
30+ contentType : "application/json" ,
31+ mimeType : "application/json" ,
32+ data : JSON . stringify ( {
33+ "param" : {
34+ userId, resendToken
35+ }
36+ } ) ,
37+ dataType : "json" ,
38+ success : function ( result ) {
39+ $ ( "#notify" ) . html ( "Email sent" ) ;
40+ $ ( "#notify" ) . closest ( ".message-wrapper" ) . fadeIn ( ) ;
41+ $ ( "#resend" ) . hide ( ) ;
42+ } ,
43+ error : function ( error ) {
44+ if ( error . responseJSON && error . responseJSON . result ) {
45+ $ ( "#error" ) . html ( error . responseJSON . result . content ) ;
46+ $ ( "#error" ) . closest ( ".message-wrapper" ) . fadeIn ( ) ;
47+ $ ( "#resend" ) . hide ( ) ;
48+ } else {
49+ $ ( "#error" ) . html ( "Unknown Error" ) ;
50+ $ ( "#error" ) . closest ( ".message-wrapper" ) . fadeIn ( ) ;
51+ }
52+ }
4653 } ) ;
54+ } ) ;
4755 } else {
48- $ ( "#resend" ) . hide ( ) ;
56+ $ ( "#resend" ) . hide ( ) ;
4957 }
5058 const errorMessage = qs [ "message" ] ;
5159 if ( errorMessage ) {
@@ -54,124 +62,72 @@ $(document).ready(function () {
5462 }
5563
5664 $ ( ".close-error" ) . on ( "click" , function ( ) {
57- $ ( this ) . closest ( ".message-wrapper" ) . fadeOut ( ) ;
65+ $ ( this ) . closest ( ".message-wrapper" ) . fadeOut ( ) ;
5866 } ) ;
59- } ) ;
60-
61- let inputVal = [ ] ;
62-
63- const isKeyInput = ( e ) => {
64- // exclude backspace, tab, shift, ctrl, alt, esc and arrow keys
65- return (
66- [ 8 , 9 , 16 , 17 , 18 , 27 , 37 , 38 , 39 , 40 , 46 ] . indexOf ( e . which ) === - 1
67- ) ;
68- } ;
69-
70- const isNumberInput = ( e ) => {
71- var charKey = e . key ;
72- return ! isNaN ( charKey ) || charKey . toLowerCase ( ) === "backspace" ;
73- } ;
74-
75- const autotab = ( e , currentPosition , to ) => {
76- const currentElement = e . currentTarget ;
77- if (
78- isKeyInput ( e ) &&
79- currentElement . getAttribute &&
80- ! e . ctrlKey &&
81- currentElement . value . length >=
82- currentElement . getAttribute ( "maxlength" )
83- ) {
84- inputVal [ currentPosition ] = currentElement . value ;
85- if ( to ) {
86- const elem = document . getElementById ( to ) ;
87- if ( elem ) {
88- elem . focus ( ) ;
89- elem . select ( ) ;
90- }
91- } else {
92- submit ( ) ;
93- }
67+ const otpcodes = $ ( ".otpcode" ) . toArray ( ) ;
68+ const handleKeyDown = ( e ) => {
69+ const currentElement = e . currentTarget ;
70+ const i = otpcodes . indexOf ( currentElement )
71+ if ( e . which === 8 && ! currentElement . value && i ) {
72+ const previousElement = otpcodes [ i - 1 ] ;
73+ previousElement . focus ( ) ;
74+ previousElement . select ( ) ;
75+ previousElement . value = "" ;
76+ }
9477 }
95- } ;
96-
97- const submit = ( ) => {
98- let formAction = qs [ "formAction" ] || "#" ;
99- const opt1 = 'https://auth.{{DOMAIN}}/continue' ;
100- const opt2 = 'https://{{AUTH0DOMAIN}}/continue' ;
101- if ( ! formAction . startsWith ( opt1 ) && ! formAction . startsWith ( opt2 ) ) {
102- // looks like XSS attack
103- $ ( '#verifyOtp' ) . attr ( 'action' , '#' ) ;
104- return false ;
78+ const handleInput = ( e ) => {
79+ const currentElement = e . currentTarget ;
80+ const i = otpcodes . indexOf ( currentElement )
81+ if ( currentElement . value && ( i + 1 ) % otpcodes . length ) {
82+ otpcodes [ i + 1 ] . focus ( ) ;
83+ otpcodes [ i + 1 ] . select ( ) ;
84+ }
85+ if ( checkForSubmit ( ) ) {
86+ console . log ( "will submit" )
87+ submit ( ) ;
88+ }
10589 }
106- $ ( '#verifyOtp' ) . attr ( 'action' , formAction ) ;
107- $ ( "#code1" ) . attr ( 'disabled' , 'disabled' ) ;
108- $ ( "#code2" ) . attr ( 'disabled' , 'disabled' ) ;
109- $ ( "#code3" ) . attr ( 'disabled' , 'disabled' ) ;
110- $ ( "#code4" ) . attr ( 'disabled' , 'disabled' ) ;
111- $ ( "#code5" ) . attr ( 'disabled' , 'disabled' ) ;
112- $ ( "#code6" ) . attr ( 'disabled' , 'disabled' ) ;
113- var otp = `${ $ ( "#code1" ) . val ( ) } ${ $ ( "#code2" ) . val ( ) } ${ $ ( "#code3" ) . val ( ) } ${ $ ( "#code4" ) . val ( ) } ${ $ ( "#code5" ) . val ( ) } ${ $ ( "#code6" ) . val ( ) } ` ;
114- $ ( "#otp" ) . val ( otp ) ;
115- $ ( "#state" ) . val ( qs [ "state" ] ) ;
116- $ ( "#returnUrl" ) . val ( qs [ "returnUrl" ] ) ;
117- $ ( "#verifyOtp" ) . submit ( ) ;
118- }
90+ const handlePaste = ( e ) => {
91+ const clipboardData = e . clipboardData || window . clipboardData || e . originalEvent . clipboardData ;
92+ const pastedData = clipboardData . getData ( "Text" ) ;
93+ const pin = pastedData . replace ( / \s / g, "" ) ;
94+ if ( ! pin ) return ;
95+ const ch = [ ...pin ] ;
96+ otpcodes . forEach ( ( el , i ) => el . value = ch [ i ] ?? "" ) ;
97+ e . preventDefault ( ) ;
98+ if ( pin . length >= otpcodes . length ) {
99+ otpcodes [ otpcodes . length - 1 ] . focus ( ) ;
100+ otpcodes [ otpcodes . length - 1 ] . select ( ) ;
101+ submit ( ) ;
102+ } else {
103+ otpcodes [ pin . length ] . focus ( ) ;
104+ otpcodes [ pin . length ] . select ( ) ;
105+ }
119106
120- const keydownHandler = ( e , prefix , currentPosition ) => {
121- const currentElement = e . currentTarget ;
122- if ( e . which === 8 && currentElement . value . length === 0 ) {
123- // go to previous input when backspace is pressed
124- const elem = document . getElementById (
125- `${ prefix } ${ currentPosition - 1 } `
126- ) ;
127- if ( elem ) {
128- elem . focus ( ) ;
129- elem . select ( ) ;
130- elem . value = "" ;
131- e . preventDefault ( ) ;
132- return ;
133- }
134107 }
135- // only allows numbers (prevents e, +, - on input number type)
136- if (
137- // currentElement.type === "number" &&
138- e . which === 69 ||
139- e . which === 187 ||
140- e . which === 189 ||
141- e . which === 190 ||
142- ! isNumberInput ( e )
143- ) {
144- e . preventDefault ( ) ;
145- return ;
108+ const checkForSubmit = ( ) => {
109+ for ( let i = 0 ; i < otpcodes . length ; i ++ ) {
110+ if ( ! otpcodes [ i ] . value ) {
111+ return false ;
112+ }
113+ }
114+ return true ;
146115 }
147- const elem = document . getElementById (
148- `${ prefix } ${ currentPosition - 1 } `
149- ) ;
150- if ( elem && ! elem . value ) {
151- e . preventDefault ( ) ;
152- return ;
116+ const submit = ( ) => {
117+ $ ( '#verifyOtp' ) . attr ( 'action' , formAction ) ;
118+ let otp = "" ;
119+ otpcodes . forEach ( element => {
120+ $ ( element ) . attr ( 'disabled' , 'disabled' ) ;
121+ otp = `${ otp } ${ $ ( element ) . val ( ) } ` ;
122+ } )
123+ $ ( "#otp" ) . val ( otp ) ;
124+ $ ( "#state" ) . val ( qs [ "state" ] ) ;
125+ $ ( "#returnUrl" ) . val ( qs [ "returnUrl" ] ) ;
126+ $ ( "#verifyOtp" ) . submit ( ) ;
153127 }
154- } ;
155-
156- const pasteHandler = ( e , prefix , currentPosition ) => {
157- const clipboardData = e . clipboardData || window . clipboardData ;
158- const pastedData = clipboardData . getData ( "Text" ) ;
159- let inputPos = currentPosition ;
160- let strIndex = 0 ;
161- let elem ;
162- do {
163- elem = document . getElementById ( `${ prefix } ${ inputPos } ` ) ;
164- if ( elem && pastedData [ strIndex ] ) {
165- elem . value = pastedData [ strIndex ] ;
166- elem . dispatchEvent ( new Event ( "input" ) ) ;
167- if ( inputPos === 6 ) {
168- submit ( ) ;
169- }
170- e . preventDefault ( ) ;
171- } else {
172- break ;
173- }
174- strIndex ++ ;
175- inputPos ++ ;
176- } while ( elem && strIndex < pastedData . length ) ;
177- } ;
128+ otpcodes . forEach ( element => {
129+ $ ( element ) . on ( "paste" , handlePaste ) ;
130+ $ ( element ) . on ( "input" , handleInput ) ;
131+ $ ( element ) . on ( "keydown" , handleKeyDown ) ;
132+ } ) ;
133+ } ) ;
0 commit comments