a mini social media app for small communities

confirm password, show/hide password, remove dead code

Changed files
+52 -22
src
templates
webapp
+1 -1
build.maple
··· 10 10 -e POSTGRES_PASSWORD=beep \ 11 11 --mount source=beep-data,target=/var/lib/postgresql/data \ 12 12 -p 5432:5432 \ 13 - postgres:15' 13 + postgres:17' 14 14 } 15 15 16 16 task:db.start = {
+46 -1
src/templates/register.html
··· 23 23 required 24 24 > 25 25 <br> 26 - <label for="password">password:</label> 26 + <label for="password">password: <a href="#" id="view-password" style="display: inline;">view</a></label> 27 27 <input 28 28 type="password" 29 29 name="password" ··· 34 34 required 35 35 > 36 36 <br> 37 + <label for="confirm-password">confirm password: <a href="#" id="view-confirm-password" style="display: inline;">view</a></label> 38 + <input 39 + type="password" 40 + name="confirm-password" 41 + id="confirm-password" 42 + pattern="@app.config.user.password_pattern" 43 + minlength="@app.config.user.password_min_len" 44 + maxlength="@app.config.user.password_max_len" 45 + required 46 + > 47 + <br> 48 + <p>passwords match: <span id="passwords-match">yes</span></p> 49 + <br> 37 50 @if app.config.instance.invite_only 38 51 <label for="invite-code">invite code:</label> 39 52 <input type="text" name="invite-code" id="invite-code" required> ··· 48 61 </form> 49 62 @end 50 63 </div> 64 + 65 + <script> 66 + const password = document.getElementById('password'); 67 + const confirm_password = document.getElementById('confirm-password'); 68 + const matches = document.getElementById('passwords-match'); 69 + 70 + const a = () => { 71 + matches.innerText = password.value==confirm_password.value ? "yes" : "no"; 72 + }; 73 + password.addEventListener('input', a); 74 + confirm_password.addEventListener('input', a); 75 + 76 + const view_password = document.getElementById('view-password'); 77 + const view_confirm_password = document.getElementById('view-confirm-password'); 78 + 79 + const b = (elm, btn) => { 80 + return event => { 81 + if (elm.getAttribute('type') == 'password') 82 + { 83 + elm.setAttribute('type', 'text'); 84 + btn.innerText = 'hide'; 85 + } 86 + else 87 + { 88 + elm.setAttribute('type', 'password') 89 + btn.innerText = 'show'; 90 + } 91 + }; 92 + }; 93 + view_password.addEventListener('click', b(password, view_password)); 94 + view_confirm_password.addEventListener('click', b(confirm_password, view_confirm_password)); 95 + </script> 51 96 52 97 @include 'partial/footer.html'
+5 -20
src/webapp/api.v
··· 11 11 // people from requesting searches with huge limits and straining the SQL server 12 12 pub const search_hard_limit = 50 13 13 14 - ////// util /////// 15 - 16 - const always_public_routes = [ 17 - '/api/user/register/', 18 - ] 19 - 20 - fn (mut app App) public_data_check(mut ctx Context) ?veb.Result { 21 - if !app.config.instance.public_data { 22 - println(ctx.req.url) 23 - if ctx.req.url in always_public_routes { 24 - return none 25 - } 26 - _ := app.whoami(mut ctx) or { 27 - ctx.error('not logged in') 28 - return ctx.redirect('/login') 29 - } 30 - } 31 - return none 32 - } 33 - 34 14 ////// user ////// 35 15 36 16 struct HcaptchaResponse { ··· 81 61 // validate password 82 62 if !app.validators.password.validate(password) { 83 63 ctx.error('invalid password') 64 + return ctx.redirect('/register') 65 + } 66 + 67 + if password != ctx.form['confirm-password'] { 68 + ctx.error('passwords do not match') 84 69 return ctx.redirect('/register') 85 70 } 86 71