Skip to content

Commit

Permalink
Fix successful and error registration route
Browse files Browse the repository at this point in the history
  • Loading branch information
sneakycrow committed Nov 25, 2024
1 parent 8961148 commit f9ef435
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 34 deletions.
19 changes: 12 additions & 7 deletions services/barn-ui/src/lib/components/Alert.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
<script lang="ts">
export let type: 'error' | 'success' | 'warning' | 'info' = 'info';
export let message: string;
export let size: 'normal' | 'small' = 'normal';
type AlertType = 'error' | 'success' | 'warning' | 'info';
type AlertSize = 'normal' | 'small';
interface Props {
class: string;
message: string;
type?: AlertType;
size?: AlertSize;
}
let { class: className, message, type = 'info', size = 'normal' }: Props = $props();
const styles = {
error: {
wrapper: 'bg-red-100 border-2 border-red-300 dark:bg-red-900/75 dark:border-red-600',
Expand Down Expand Up @@ -31,9 +37,8 @@
</script>

<div
class="flex items-center justify-center rounded-md {size === 'small'
? 'p-2'
: 'p-4'} text-center {styles[type].wrapper}"
class="flex items-center justify-center rounded-md p-2 text-center {styles[type]
.wrapper} {className}"
>
<div class="flex-shrink-0">
{#if type === 'error'}
Expand Down Expand Up @@ -91,7 +96,7 @@
{/if}
</div>
<div class="ml-3">
<p class="{size === 'small' ? 'text-xs' : 'text-sm'} font-medium {styles[type].text}">
<p class="text-xs font-medium {styles[type].text}">
{message}
</p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion services/barn-ui/src/lib/components/Form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
class="mt-8 w-full max-w-sm flex-grow rounded border-2 border-secondary-900 bg-white p-6 shadow-md dark:border-primary-800 dark:bg-primary-900 dark:shadow-xl"
>
{#if error}
<Alert type="error" message={error} />
<Alert type="error" message={error} class="mb-4" />
{/if}

<slot />
Expand Down
52 changes: 34 additions & 18 deletions services/barn-ui/src/routes/(guest)/register/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Actions } from './$types';
import { env } from '$env/dynamic/private';

export const actions = {
default: async ({ request }) => {
default: async ({ request, cookies }) => {
const data = await request.formData();
const username = data.get('username');
const email = data.get('email');
Expand All @@ -26,30 +26,46 @@ export const actions = {
email: email?.toString()
});
}

const response = await fetch(`${env.API_URL}/auth/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
let response = null;
try {
response = await fetch(`${env.API_URL}/auth/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: username.toString(),
email: email.toString(),
password: password.toString(),
password_confirmation: passwordConfirmation.toString()
})
});
} catch (e) {
console.error('Error sending registration request to api', e);
return fail(500, {
error: 'Failed to connect to server. Please try again.',
username: username.toString(),
email: email.toString(),
password: password.toString(),
password_confirmation: passwordConfirmation.toString()
})
});
email: email.toString()
});
}

if (!response.ok) {
const errorData = await response.json();
const res = await response.json();
return fail(response.status, {
error: errorData.message || 'Failed to create account. Please try again.',
error: res.message,
username: username.toString(),
email: email.toString()
});
}

// Redirect on success
return redirect(303, '/login');
// Login the user with the token in the response
const json = await response.json();
// Set the cookie so we can get the user again later
cookies.set('jwt', json.token, {
path: '/',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24), // 24 hours
sameSite: true
});
// Redirect the user
throw redirect(303, '/');
}
} satisfies Actions;
62 changes: 54 additions & 8 deletions services/silo-api/src/routes/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,75 @@ pub struct ErrorResponse {
pub async fn register(
State(state): State<Arc<AppState>>,
Json(payload): Json<RegisterRequest>,
) -> impl IntoResponse {
) -> Result<Json<AuthResponse>, (StatusCode, Json<ErrorResponse>)> {
// Validate inputs
if payload.password != payload.password_confirmation {
return Err(StatusCode::BAD_REQUEST);
return Err((
StatusCode::BAD_REQUEST,
Json(ErrorResponse {
message: "Passwords do not match".to_string(),
}),
));
}

if payload.username.is_empty() || payload.email.is_empty() || payload.password.is_empty() {
return Err(StatusCode::BAD_REQUEST);
return Err((
StatusCode::BAD_REQUEST,
Json(ErrorResponse {
message: "All fields are required".to_string(),
}),
));
}

// Create a new user
let mut user = User::new(payload.email, payload.username, payload.password);
// Make sure to hash the password
user.hash_password()
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
user.hash_password().map_err(|_| {
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(ErrorResponse {
message: "Failed to process password".to_string(),
}),
)
})?;

// Insert the new user into the database
match user.insert(&state.db).await {
Ok(user) => {
let token =
encode_jwt(&user.id.to_string()).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let token = encode_jwt(&user.id.to_string()).map_err(|_| {
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(ErrorResponse {
message: "Failed to generate authentication token".to_string(),
}),
)
})?;
Ok(Json(AuthResponse { token }))
}
Err(_e) => Err(StatusCode::BAD_REQUEST),
Err(e) => {
if e.as_database_error()
.and_then(|e| e.code())
.filter(|c| c == "23505")
.is_some()
{
// non-unique error
tracing::error!("Non-unique user registration error: {e}");
return Err((
StatusCode::CONFLICT,
Json(ErrorResponse {
message: "Username or email is already registered".to_string(),
}),
));
}
// Other db error
tracing::error!("Database error during registration: {e}");
Err((
StatusCode::INTERNAL_SERVER_ERROR,
Json(ErrorResponse {
message: "An unexpected error occurred".to_string(),
}),
))
}
}
}

Expand Down

0 comments on commit f9ef435

Please sign in to comment.