1
1
{% extends "base.html" %}
2
2
3
+ {% set commitment_text = "I have read the ground rules and commit to not publish pwn.college writeups on the internet." %}
4
+
3
5
{% block content %}
4
6
< div class ="jumbotron ">
5
7
< div class ="container ">
@@ -22,10 +24,22 @@ <h3>Bug Bounties</h3>
22
24
If you find a vulnerability in this platform, please < a href ="mailto:pwn-college@asu.edu "> email</ a > us rather than pwn us.
23
25
We'll appreciate it, and you'll get extra credit (if you're an ASU student) or an awesome scoreboard award!</ p >
24
26
27
+ < div class ="form-group " id ="commitment-section ">
28
+ < div class ="alert alert-warning ">
29
+ To register, please type the following commitment exactly as shown:
30
+ < br > < br >
31
+ < strong id ="commitment-text "> {{ commitment_text }}</ strong >
32
+ </ div >
33
+ < input type ="text " id ="commitment-input " class ="form-control " placeholder ="Type the commitment above " autocomplete ="off ">
34
+ < small class ="form-text text-muted " id ="commitment-feedback ">
35
+ Please type the commitment exactly as shown above to enable registration
36
+ </ small >
37
+ </ div >
38
+
25
39
< h2 > Sign Up!</ h2 >
26
40
{% with form = Forms.auth.RegistrationForm() %}
27
41
{% from "macros/forms.html" import render_extra_fields %}
28
- < form method ="post " accept-charset ="utf-8 " autocomplete ="off " role ="form ">
42
+ < form method ="post " accept-charset ="utf-8 " autocomplete ="off " role ="form " id =" registration-form " >
29
43
< div class ="form-group ">
30
44
< b > {{ form.name.label }}</ b >
31
45
{{ form.name(class="form-control", value=name) }}
@@ -47,13 +61,16 @@ <h2>Sign Up!</h2>
47
61
Password used to log into your account
48
62
</ small >
49
63
</ div >
64
+
50
65
{{ form.nonce() }}
66
+
67
+ < input type ="hidden " id ="commitment-verified " name ="commitment_verified " value ="">
51
68
52
69
{{ render_extra_fields(form.extra) }}
53
70
54
71
< div class ="row pt-3 ">
55
72
< div class ="col-md-12 ">
56
- {{ form.submit(class="btn btn-md btn-primary btn-outlined float-right") }}
73
+ {{ form.submit(class="btn btn-md btn-primary btn-outlined float-right btn-disabled", id="register-submit", style="opacity: 0.5; cursor: not-allowed; ") }}
57
74
</ div >
58
75
</ div >
59
76
@@ -76,4 +93,108 @@ <h2>Sign Up!</h2>
76
93
{% endblock %}
77
94
78
95
{% block scripts %}
96
+ < style >
97
+ @keyframes shake {
98
+ 0% , 100% { transform : translateX (0 ); }
99
+ 10% , 30% , 50% , 70% , 90% { transform : translateX (-5px ); }
100
+ 20% , 40% , 60% , 80% { transform : translateX (5px ); }
101
+ }
102
+ </ style >
103
+ < script >
104
+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
105
+ const commitmentText = { { commitment_text | tojson } } ;
106
+ const commitmentInput = document . getElementById ( 'commitment-input' ) ;
107
+ const commitmentFeedback = document . getElementById ( 'commitment-feedback' ) ;
108
+ const registerButton = document . getElementById ( 'register-submit' ) ;
109
+ const registerForm = document . getElementById ( 'registration-form' ) ;
110
+ const commitmentVerifiedField = document . getElementById ( 'commitment-verified' ) ;
111
+ let commitmentValid = false ;
112
+
113
+ function normalizeText ( text ) {
114
+ return text . toLowerCase ( ) . replace ( / [ ^ a - z ] / g, '' ) . split ( '' ) . sort ( ) . join ( '' ) ;
115
+ }
116
+
117
+ function validateCommitment ( ) {
118
+ const userInput = commitmentInput . value . trim ( ) ;
119
+
120
+ if ( userInput === '' ) {
121
+ commitmentValid = false ;
122
+ commitmentVerifiedField . value = '' ;
123
+ commitmentInput . classList . remove ( 'is-valid' , 'is-invalid' ) ;
124
+ commitmentFeedback . textContent = 'Please type the commitment exactly as shown above to enable registration' ;
125
+ commitmentFeedback . classList . remove ( 'text-success' , 'text-danger' ) ;
126
+ commitmentFeedback . classList . add ( 'text-muted' ) ;
127
+
128
+ registerButton . style . opacity = '0.5' ;
129
+ registerButton . style . cursor = 'not-allowed' ;
130
+ registerButton . classList . add ( 'btn-disabled' ) ;
131
+ } else {
132
+ const normalizedUser = normalizeText ( userInput ) ;
133
+ const normalizedCommitment = normalizeText ( commitmentText ) ;
134
+
135
+ if ( normalizedUser === normalizedCommitment ) {
136
+ commitmentValid = true ;
137
+ commitmentVerifiedField . value = 'verified' ;
138
+ commitmentInput . classList . remove ( 'is-invalid' ) ;
139
+ commitmentInput . classList . add ( 'is-valid' ) ;
140
+ commitmentFeedback . textContent = 'Thank you for helping keep pwn.college viable!' ;
141
+ commitmentFeedback . classList . remove ( 'text-muted' , 'text-danger' ) ;
142
+ commitmentFeedback . classList . add ( 'text-success' ) ;
143
+
144
+ registerButton . style . opacity = '1' ;
145
+ registerButton . style . cursor = 'pointer' ;
146
+ registerButton . classList . remove ( 'btn-disabled' ) ;
147
+ } else {
148
+ commitmentValid = false ;
149
+ commitmentVerifiedField . value = '' ;
150
+ commitmentInput . classList . remove ( 'is-valid' ) ;
151
+ commitmentInput . classList . add ( 'is-invalid' ) ;
152
+ commitmentFeedback . textContent = 'Please type the commitment as shown above' ;
153
+ commitmentFeedback . classList . remove ( 'text-muted' , 'text-success' ) ;
154
+ commitmentFeedback . classList . add ( 'text-danger' ) ;
155
+
156
+ registerButton . style . opacity = '0.5' ;
157
+ registerButton . style . cursor = 'not-allowed' ;
158
+ registerButton . classList . add ( 'btn-disabled' ) ;
159
+ }
160
+ }
161
+ }
162
+
163
+ function showCommitmentReminder ( ) {
164
+ alert ( 'Please type the commitment exactly as shown to enable registration.' ) ;
165
+ document . getElementById ( 'commitment-section' ) . scrollIntoView ( { behavior : 'smooth' , block : 'center' } ) ;
166
+ commitmentInput . focus ( ) ;
167
+ commitmentInput . style . animation = 'shake 0.5s' ;
168
+ setTimeout ( ( ) => {
169
+ commitmentInput . style . animation = '' ;
170
+ } , 500 ) ;
171
+ }
172
+
173
+ commitmentInput . addEventListener ( 'input' , validateCommitment ) ;
174
+ commitmentInput . addEventListener ( 'paste' , function ( ) {
175
+ setTimeout ( validateCommitment , 10 ) ;
176
+ } ) ;
177
+
178
+ registerForm . addEventListener ( 'submit' , function ( e ) {
179
+ if ( ! commitmentValid ) {
180
+ e . preventDefault ( ) ;
181
+ e . stopPropagation ( ) ;
182
+ showCommitmentReminder ( ) ;
183
+ return false ;
184
+ }
185
+ return true ;
186
+ } ) ;
187
+
188
+ registerButton . addEventListener ( 'click' , function ( e ) {
189
+ if ( ! commitmentValid ) {
190
+ e . preventDefault ( ) ;
191
+ e . stopPropagation ( ) ;
192
+ showCommitmentReminder ( ) ;
193
+ return false ;
194
+ }
195
+ } ) ;
196
+
197
+ validateCommitment ( ) ;
198
+ } ) ;
199
+ </ script >
79
200
{% endblock %}
0 commit comments