added login and checking of roles to admin page
ci.vdhsn.com/push Build is failing
Details
ci.vdhsn.com/push Build is failing
Details
parent
abb8e565cd
commit
e891ada9e8
@ -0,0 +1,95 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
interface FormValidations {
|
||||
email?: boolean;
|
||||
general?: boolean;
|
||||
}
|
||||
|
||||
export const validations: FormValidations = {};
|
||||
|
||||
let email: string = '';
|
||||
let password: string = '';
|
||||
let passwordConfirmation: string = '';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const execLogin = () =>
|
||||
dispatch('login', {
|
||||
email,
|
||||
password
|
||||
});
|
||||
|
||||
const execRegister = () => {
|
||||
if (password !== passwordConfirmation) {
|
||||
console.log("password and confirm don't match");
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch('register', {
|
||||
email,
|
||||
password
|
||||
});
|
||||
};
|
||||
|
||||
let showPassword = false;
|
||||
let showRegistration = false;
|
||||
|
||||
const revealPass = () => (showPassword = !showPassword);
|
||||
const toggleFormType = () => (showRegistration = !showRegistration);
|
||||
|
||||
$: ctaTxt = showRegistration ? 'Up' : 'In';
|
||||
$: toggleCtaTxt = !showRegistration ? 'Up' : 'In';
|
||||
$: ctaFunc = showRegistration ? execRegister : execLogin;
|
||||
</script>
|
||||
|
||||
<form class="flex" style="max-width: 600px;" on:submit|preventDefault={ctaFunc}>
|
||||
<span class="flex flex-col justify-around w-20">
|
||||
<label for="email"> Email </label>
|
||||
<label for="password"> Password </label>
|
||||
</span>
|
||||
|
||||
<span class="flex flex-col">
|
||||
<span class="flex">
|
||||
<input
|
||||
class="px-2 py-1 border-r-0 grow invalid:border-red-500 invalid:border-2"
|
||||
type="email"
|
||||
required
|
||||
bind:value={email}
|
||||
/>
|
||||
<button class="border-l-0 px-2 py-1 disabled:text-gray-500">
|
||||
Sign {ctaTxt}
|
||||
</button>
|
||||
</span>
|
||||
<span class="flex">
|
||||
<input
|
||||
class="px-2 py-1 w-full"
|
||||
name="password"
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
required
|
||||
placeholder={showRegistration ? 'Password' : ''}
|
||||
on:blur={() => (showPassword = false)}
|
||||
on:change={(evt) => (password = evt?.target?.value)}
|
||||
/>
|
||||
{#if showRegistration}
|
||||
<input
|
||||
class="px-2 py-1 border-r-0 invalid:border-red-500 invalid:border-2"
|
||||
name="confirm_password"
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
pattern={password}
|
||||
required
|
||||
placeholder="Confirm Password"
|
||||
on:blur={() => (showPassword = false)}
|
||||
on:change={(evt) => (passwordConfirmation = evt?.target?.value)}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="border-l-0 px-2 py-1 w-16"
|
||||
tabindex="-1"
|
||||
on:click|stopPropagation={revealPass}
|
||||
>
|
||||
{showPassword ? 'Hide' : 'Show'}
|
||||
</button>
|
||||
{/if}
|
||||
</span>
|
||||
</span>
|
||||
</form>
|
@ -0,0 +1,119 @@
|
||||
import { browser } from '$app/environment';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
const API_HOST = `${browser ? '' : env.BH_CLIENT_INTERNAL_API_HOST}/api/v1`;
|
||||
|
||||
interface SessionInfo {
|
||||
sessionId?: string;
|
||||
account?: {
|
||||
id: string;
|
||||
email: string;
|
||||
role: 'BIDDER' | 'USER' | 'ADMINISTRATOR' | 'ANONYMOUS';
|
||||
createdTs: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const getSession = () => {
|
||||
if (browser) {
|
||||
const strSession = localStorage.getItem('bh-session');
|
||||
if (strSession) {
|
||||
const data = JSON.parse(strSession);
|
||||
if (data?.sessionId) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
export const session = writable<SessionInfo>(getSession(), (set) => {
|
||||
const session = getSession();
|
||||
if (session) {
|
||||
set(session);
|
||||
}
|
||||
});
|
||||
|
||||
interface LoginAction {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export const loginAction = async ({ email, password }: LoginAction): Promise<SessionInfo> => {
|
||||
try {
|
||||
const sessionStr = localStorage.getItem('bh-session');
|
||||
if (sessionStr) {
|
||||
const data = JSON.parse(sessionStr);
|
||||
if (data.sessionId) {
|
||||
console.log('already authenticated');
|
||||
session.set(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
localStorage.removeItem('bh-session');
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
new Request(`${API_HOST}/user`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email,
|
||||
password
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
|
||||
if (data.sessionId) {
|
||||
localStorage.setItem('bh-session', JSON.stringify(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
console.trace("got this on login attempt:", data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
interface RegisterAction {
|
||||
email: string;
|
||||
password: string;
|
||||
role?: string;
|
||||
}
|
||||
export const registerAction = async ({ email, password, role }: RegisterAction) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
new Request(`${API_HOST}/user`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email,
|
||||
password,
|
||||
role: role || 'USER'
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
export const logoutAction = () => {
|
||||
localStorage.removeItem('bh-session');
|
||||
session.set({});
|
||||
};
|
@ -0,0 +1,64 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
aapi "git.vdhsn.com/barretthousen/barretthousen/src/auth/api/grpc"
|
||||
"git.vdhsn.com/barretthousen/barretthousen/src/auth/internal/domain"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func NewAuthServiceClient(conn grpc.ClientConnInterface) *AuthServiceClient {
|
||||
return &AuthServiceClient{
|
||||
AuthClient: aapi.NewAuthClient(conn),
|
||||
}
|
||||
}
|
||||
|
||||
type AuthServiceClient struct {
|
||||
aapi.AuthClient
|
||||
}
|
||||
|
||||
type CheckSessionParams struct {
|
||||
SessionID string
|
||||
}
|
||||
|
||||
func (asc *AuthServiceClient) CheckSession(ctx context.Context, in CheckSessionParams) (out Account, err error) {
|
||||
if in.SessionID == "" {
|
||||
err = domain.ErrInvalidSession
|
||||
return
|
||||
}
|
||||
var sessionIDInt int
|
||||
|
||||
if sessionIDInt, err = strconv.Atoi(in.SessionID); err != nil {
|
||||
return
|
||||
}
|
||||
var accountResult *aapi.Account
|
||||
|
||||
if accountResult, err = asc.GetSession(ctx, &aapi.SessionFilter{
|
||||
SessionId: int32(sessionIDInt),
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = Account{
|
||||
ID: int(accountResult.Id),
|
||||
Created: accountResult.CreatedTs.AsTime(),
|
||||
Email: accountResult.Email,
|
||||
Verified: accountResult.VerifiedTs.AsTime(),
|
||||
Role: accountResult.Role,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Account struct {
|
||||
ID int `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
Verified time.Time `json:"verified,omitempty"`
|
||||
Email string `json:"email"`
|
||||
PasswordHash string `json:"password_hash,omitempty"`
|
||||
Role string `json:"role"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
Loading…
Reference in new issue