Skip to content

Commit cf54cfc

Browse files
committed
fix(auth): fix disabled button styling and password policy JS serialization
Move .button into auth.scss at the .main_container level so the .button:global(.Mui-disabled) override wins by specificity (0,3,0 vs 0,2,0) rather than depending on source order. Harden shape_pattern and allowed_special_characters in register.blade.php with Js::from(), matching the treatment already applied to the other three passwordPolicy strings. {{ }} encodes & as & inside a script block, which corrupted the regex character class and caused the client to accept passwords the server rejects. Add PasswordPolicyRenderingTest to guard against this class of rendering bug.
1 parent 705dea3 commit cf54cfc

5 files changed

Lines changed: 66 additions & 14 deletions

File tree

resources/js/reset_password/reset_password.module.scss

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
text-align: center;
1717
}
1818

19-
.button {
20-
width: 380px;
21-
color: white;
22-
background-color: $base-color-dark;
23-
}
24-
2519
.error_label {
2620
color: #f44336;
2721
font-size: 0.75rem;

resources/js/signup/signup.module.scss

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@
2020
text-align: center;
2121
}
2222

23-
.button {
24-
width: 380px;
25-
color: white;
26-
background-color: black;
27-
}
28-
2923
.error_label {
3024
color: #f44336;
3125
font-size: 0.75rem;

resources/styles/auth.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,15 @@
6464
letter-spacing: 0.5em;
6565
}
6666

67+
.button {
68+
width: 380px;
69+
color: white;
70+
background-color: black;
71+
72+
&:global(.Mui-disabled) {
73+
background-color: rgba(0, 0, 0, 0.12);
74+
color: rgba(0, 0, 0, 0.26);
75+
}
76+
}
77+
6778
}

resources/views/auth/register.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
const passwordPolicy = {
2727
min_length: {{ Config::get("auth.password_min_length") }},
2828
max_length: {{ Config::get("auth.password_max_length") }},
29-
shape_pattern: '{{ Config::get("auth.password_shape_pattern") }}',
30-
allowed_special_characters: '{{ Config::get("auth.password_allowed_special_characters") }}',
29+
shape_pattern: '{{ Illuminate\Support\Js::from(Config::get("auth.password_shape_pattern")) }}',
30+
allowed_special_characters: '{{ Illuminate\Support\Js::from(Config::get("auth.password_allowed_special_characters")) }}',
3131
allowed_special_characters_text: {{ Illuminate\Support\Js::from(Config::get("auth.password_allowed_special_characters_text")) }},
3232
shape_warning: {{ Illuminate\Support\Js::from(Config::get("auth.password_shape_warning")) }},
3333
shape_list: {{ Illuminate\Support\Js::from(Config::get("auth.password_shape_list")) }}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php namespace Tests;
2+
/**
3+
* Copyright 2026 OpenStack Foundation
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
**/
14+
15+
use Illuminate\Support\Facades\Config;
16+
use Illuminate\Support\ViewErrorBag;
17+
18+
class PasswordPolicyRenderingTest extends TestCase
19+
{
20+
/**
21+
* The regex the browser receives must classify passwords exactly as the
22+
* server-side one does. Probes are all 10-30 chars so length is never the
23+
* discriminator — only the special-character class is under test.
24+
*/
25+
public function test_rendered_signup_pattern_agrees_with_server_pattern(): void
26+
{
27+
$html = view('auth.register', [
28+
'countries' => [],
29+
'client_id' => '',
30+
'redirect_uri' => '',
31+
'errors' => new ViewErrorBag(),
32+
])->render();
33+
34+
$this->assertSame(1, preg_match('/shape_pattern:\s*(.+?),\R/', $html, $m));
35+
36+
// Resolve the \uXXXX escapes a JS parser would resolve in the literal.
37+
// Trim both single quotes ({{ }} format) and double quotes (Js::from format).
38+
$client = preg_replace_callback(
39+
'/\\\\u([0-9a-fA-F]{4})/',
40+
fn ($u) => mb_chr(hexdec($u[1])),
41+
trim($m[1], "\"'")
42+
);
43+
$server = Config::get('auth.password_shape_pattern');
44+
45+
foreach (['Passwordma1', 'Passw0rdabc', ';Passw0rdaa', 'Valid1Pass!'] as $probe) {
46+
$this->assertSame(
47+
(bool) preg_match("/{$server}/", $probe),
48+
(bool) preg_match("/{$client}/", $probe),
49+
"rendered and server patterns disagree on '{$probe}'"
50+
);
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)