Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
harishmohanraj committed Nov 11, 2024
1 parent 1d0de03 commit cbf8a4a
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 64 deletions.
15 changes: 4 additions & 11 deletions fastagency/ui/mesop/auth/basic_auth/basic_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ def _verify_password(self, password: str, password_hash: str) -> bool:

def is_authorized(self, username: str, password: str) -> bool:
if username not in self.allowed_users:
raise ValueError("Invalid username or password")
return False

password_hash = self.allowed_users[username]
if not self._verify_password(password, password_hash):
raise ValueError("Invalid username or password")
return False

return True

Expand All @@ -54,14 +54,8 @@ def on_auth_changed(self, e: mel.WebEvent) -> None:

username, password = e.value["username"], e.value["password"]

try:
if not self.is_authorized(username, password):
raise me.MesopUserException(
"You are not authorized to access this application. "
"Please contact the application administrators for access."
)
except ValueError as e:
raise me.MesopUserException(str(e)) from e
if not self.is_authorized(username, password):
raise me.MesopUserException("Invalid username or password")

state.authenticated_user = username

Expand All @@ -78,7 +72,6 @@ def auth_component(self) -> me.component:
else:
with me.box(style=styles.login_box): # noqa: SIM117
with me.box(style=styles.login_btn_container):
me.text("Sign in to your account", style=styles.header_text)
basic_auth_component(
on_auth_changed=self.on_auth_changed,
authenticated_user=state.authenticated_user,
Expand Down
239 changes: 186 additions & 53 deletions javascript/basic_auth_component.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,144 @@
import {
LitElement,
css,
html,
} from "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js";

class BasicAuthComponent extends LitElement {
static styles = css`
:host {
display: block;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}
.auth-container {
width: 100%;
max-width: 400px;
margin: 1rem auto;
padding: 2rem;
border-radius: 8px;
background: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
form {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.input-group {
position: relative;
}
.input-group input {
width: 96%;
padding: 0.75rem 0 0.75rem 0.5rem;
font-size: 1rem;
border: 1px solid #e2e8f0;
border-radius: 6px;
background: #f8fafc;
transition: all 0.2s ease;
}
.input-group input:focus {
outline: none;
border-color: #3b82f6;
background: white;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
.input-group input::placeholder {
color: #94a3b8;
}
.auth-button {
width: 100%;
padding: 0.75rem 1.5rem;
font-size: 1rem;
font-weight: 500;
color: white;
background: #3b82f6;
border: none;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
.auth-button:hover {
background: #2563eb;
transform: translateY(-1px);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.auth-button:active {
transform: translateY(0);
box-shadow: none;
}
.auth-button:disabled {
background: #94a3b8;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.error {
padding: 0.75rem 1rem;
margin-bottom: 1rem;
color: #dc2626;
background: #fee2e2;
border: 1px solid #fecaca;
border-radius: 6px;
font-size: 0.875rem;
}
/* Sign out button specific styles */
.auth-container:has(> .auth-button) {
padding: 0rem;
box-shadow: none;
background: transparent;
margin-top:0rem;
}
.auth-container:has(> .auth-button) .auth-button {
width: auto;
max-width: 200px;
background: #ef4444;
border: 1px solid #dc2626;
padding: 0.5rem 0.75rem;
font-size: 0.75rem;
}
.auth-container:has(> .auth-button) .auth-button:hover {
background: #dc2626;
}
/* Loading state styles */
.auth-button.loading {
position: relative;
color: transparent;
}
.auth-button.loading::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 20px;
height: 20px;
border: 2px solid white;
border-radius: 50%;
border-top-color: transparent;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: translate(-50%, -50%) rotate(360deg);
}
}
`;
static properties = {
isSignedIn: { type: Boolean },
authChanged: { type: String },
Expand Down Expand Up @@ -54,12 +189,10 @@ class BasicAuthComponent extends LitElement {
// Dispatch auth event with credentials using MesopEvent
this.dispatchEvent(new MesopEvent(this.authChanged, credentials));

// Clear form
this.username = '';
this.password = '';
this.error = '';
this.isSignedIn = true;

// this.error = '';
// this.isSignedIn = true;

} catch (error) {
this.error = error.message || 'Authentication failed';
Expand Down Expand Up @@ -99,55 +232,55 @@ class BasicAuthComponent extends LitElement {
render() {
// Use conditional rendering without style display properties
return html`
<div
class="auth-container"
style="${this.isSignedIn ? "" : "display: none"}"
>
<button
style="background-color:#ffffff"
class="auth-button"
@click="${this.signOut}"
>
<span class="button-text">Sign out</span>
</button>
</div>
<div
class="auth-container"
style="${this.isSignedIn ? "display: none" : ""}"
>
<form @submit="${this.handleSubmit}">
${this.error ? html`<div class="error">${this.error}</div>` : ''}
<div class="input-group">
<input
type="email"
placeholder="Email"
.value="${this.username}"
@input="${this.handleUsernameChange}"
required
/>
</div>
<div class="input-group">
<input
type="password"
placeholder="Password"
.value="${this.password}"
@input="${this.handlePasswordChange}"
required
/>
</div>
<button
type="submit"
class="auth-button"
?disabled="${!this.username || !this.password}"
>
<span class="button-text">Sign in</span>
</button>
</form>
</div>
`;
<div
class="auth-container"
style="${this.isSignedIn ? "" : "display: none"}"
>
<button
class="auth-button"
@click="${this.signOut}"
>
<span class="button-text">Sign out</span>
</button>
</div>
<div
class="auth-container"
style="${this.isSignedIn ? "display: none" : ""}"
>
<h1>Sign in to your account</h1>
<form @submit="${this.handleSubmit}">
${this.error ? html`<div class="error">${this.error}</div>` : ''}
<div class="input-group">
<input
type="email"
placeholder="Email"
.value="${this.username}"
@input="${this.handleUsernameChange}"
required
/>
</div>
<div class="input-group">
<input
type="password"
placeholder="Password"
.value="${this.password}"
@input="${this.handlePasswordChange}"
required
/>
</div>
<button
type="submit"
class="auth-button ${this.loading ? 'loading' : ''}"
?disabled="${!this.username || !this.password}"
>
<span class="button-text">Sign in</span>
</button>
</form>
</div>
`;
}
}

Expand Down

0 comments on commit cbf8a4a

Please sign in to comment.