Skip to content

Commit

Permalink
user registration
Browse files Browse the repository at this point in the history
  • Loading branch information
khanzadimahdi committed Aug 17, 2024
1 parent a49b18c commit 9719b2a
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 59 deletions.
8 changes: 7 additions & 1 deletion backend/application/auth/verify/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package verify

import (
"crypto/rand"
"encoding/base64"
"errors"

"github.com/khanzadimahdi/testproject/application/auth"
Expand Down Expand Up @@ -32,7 +33,12 @@ func (uc *UseCase) Execute(request Request) (*Response, error) {
}, nil
}

claims, err := uc.jwt.Verify(request.Token)
registrationToken, err := base64.URLEncoding.DecodeString(request.Token)
if err != nil {
return nil, err
}

claims, err := uc.jwt.Verify(string(registrationToken))
if err != nil {
return &Response{
ValidationErrors: validationErrors{
Expand Down
7 changes: 4 additions & 3 deletions backend/application/auth/verify/usecase_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package verify

import (
"encoding/base64"
"errors"
"github.com/khanzadimahdi/testproject/domain"
"github.com/stretchr/testify/mock"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

"github.com/khanzadimahdi/testproject/application/auth"
"github.com/khanzadimahdi/testproject/domain"
"github.com/khanzadimahdi/testproject/domain/user"
"github.com/khanzadimahdi/testproject/infrastructure/crypto/ecdsa"
crypto "github.com/khanzadimahdi/testproject/infrastructure/crypto/mock"
Expand Down Expand Up @@ -246,5 +247,5 @@ func generateToken(t *testing.T, j *jwt.JWT, u user.User, expiresAt time.Time, a
token, err := j.Generate(b.Build())
assert.NoError(t, err)

return token
return base64.URLEncoding.EncodeToString([]byte(token))
}
48 changes: 29 additions & 19 deletions frontend/components/navbar.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
<template>
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container">
<NuxtLink class="navbar-brand" to="/">
<strong>طرح‌چه</strong>
</NuxtLink>
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container">
<NuxtLink class="navbar-brand" to="/">
<strong>طرح‌چه</strong>
</NuxtLink>

<button class="navbar-toggler" type="button" @click="toggle()">
<span class="navbar-toggler-icon"></span>
</button>
<button class="navbar-toggler" type="button" @click="toggle()">
<span class="navbar-toggler-icon"></span>
</button>

<div :class="{'show': value}" class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<NuxtLink v-if="useAuth().isLogin()" class="nav-link" to="/dashboard">پنل کاربری</NuxtLink>
<NuxtLink v-else class="nav-link" to="/auth/login">ورود</NuxtLink>
</li>
</ul>
</div>
</div>
</nav>
<div :class="{'show': value}" class="collapse navbar-collapse">
<ul v-if="useAuth().isLogin()" class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<NuxtLink class="nav-link" to="/dashboard">پنل کاربری</NuxtLink>
</li>
<li class="nav-item">
<button class="nav-link" type="button" @click="useAuth().logout()">خروج</button>
</li>
</ul>
<ul v-else class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<NuxtLink class="nav-link" to="/auth/register">ثبت نام</NuxtLink>
</li>
<li class="nav-item">
<NuxtLink class="nav-link" to="/auth/login">ورود</NuxtLink>
</li>
</ul>
</div>
</div>
</nav>
</template>

<script setup>
import { useToggle } from '@vueuse/core'
import {useToggle} from '@vueuse/core'
const [value, toggle] = useToggle()
</script>
51 changes: 50 additions & 1 deletion frontend/composables/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {jwtDecode} from "jwt-decode"

const cookieName = "auth"

const homePage = '/'
const loginPage = '/auth/login'
const dashboardPage = '/dashboard'

Expand Down Expand Up @@ -65,7 +66,53 @@ async function logout() {
cookie.value = null
}

await navigateTo({path: loginPage})
await navigateTo({path: homePage})
}

async function register(identity: string) {
const {data, error} = await useFetch(
useApiUrlResolver().resolve("api/auth/register"),
{
method: "POST",
body: {
"identity": identity,
}
}
)

if (error.value) {
console.log({
statusCode: error.value.statusCode,
data: error.value.data,
})

throw new Error("registration failed");
}
}

async function verify(token: string, name:string, username:string, password:string, repassword:string) {
const {data, error} = await useFetch(
useApiUrlResolver().resolve("api/auth/verify"),
{
method: "POST",
body: {
"token": token,
"name": name,
"username": username,
"password": password,
"repassword": repassword,
}
}
)

if (error.value) {
console.log({
statusCode: error.value.statusCode,
data: error.value.data,
})

throw new Error("verification failed");
}
}

function accessToken() {
Expand Down Expand Up @@ -153,6 +200,8 @@ export function useAuth() {
isLogin: isLogin,
forgotPassword: forgotPassword,
resetPassword: resetPassword,
register: register,
verify: verify,
}
}

Expand Down
100 changes: 66 additions & 34 deletions frontend/pages/auth/register.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,72 @@
<div class="w-100 d-none d-md-block" id="register-cover"></div>
<div class="w-100 mt-3 mt-0 p-4">
<h3 class="mb-4 text-center ">ثبت نام</h3>
<form action="#" class="signin-form d-flex flex-column" @submit.prevent="login()">
<div class="form-group mt-2">
<input :class="{ 'is-invalid': errors.identity }" type="text" placeholder="ایمیل"
class="input form-control py-2 " v-model="params.identity" required>
<div v-if="errors.identity" class="invalid-feedback">
{{ errors.identity }}
</div>
</div>
<div class="form-group my-4">
<input :class="{ 'is-invalid': errors.password }" type="password" placeholder="کلمه عبور"
class="input form-control py-2 " v-model="params.password" required>
<div v-if="errors.password" class="invalid-feedback">
{{ errors.password }}
<form action="#" class="signin-form d-flex flex-column" @submit.prevent="register()">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>

<div>
<div class="alert alert-info">
<h4 class="alert-heading">
<svg class="bi flex-shrink-0 m-2" width="24" height="24" role="img" aria-label="Info:"><use xlink:href="#info-fill"/></svg>
<span>توجه کنید</span>
</h4>
<hr>
<ul class="small">
<li>بعد از ثبت نام یک پیام در ایمیل خود دریافت خواهید کرد و با استفاده از آن میتوانید باقی مراحل ثبت
نام را انجام دهید.
</li>
<li>برای ثبت نام از ایمیل خود استفاده کنید.</li>
<li>چنانچه مراحل ثبت نام را قبلا کامل کرده اید میتوانید
<nuxt-link to="/auth/login">وارد حساب کاربری</nuxt-link>
خود شوید.
</li>
</ul>
</div>
</div>
<div class="form-group">
<button :disabled="params.loading" type="submit"
class="form-control btn btn-primary rounded submit px-3">
<span v-if="!params.loading">ثبت نام</span>
<div v-else class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
<section class="alert alert-success text-center" v-if="params.showNextSteps">
<p class="mb-0">
<svg class="bi flex-shrink-0 mx-2" width="24" height="24" role="img" aria-label="Success:"><use xlink:href="#check-circle-fill"/></svg>
<span>لینک ثبت نام برای شما ارسال شد. لطفا ایمیل خود را بررسی کنید.</span>
</p>
</section>
<section v-else>
<div class="form-group my-2">
<input :class="{ 'is-invalid': errors.identity }" type="text" placeholder="ایمیل"
class="input form-control py-2 " v-model="params.identity" required>
<div v-if="errors.identity" class="invalid-feedback">
{{ errors.identity }}
</div>
</button>
</div>
<div
class="form-group d-flex flex-column flex-md-row mt-2 pt-2 justify-content-md-end gap-3 align-items-md-center">
<div>
<nuxt-link to="/auth/forgot-password" class="btn btn-outline-danger w-100 btn-sm ">بازیابی کلمه عبور
</nuxt-link>
</div>
<div>
<nuxt-link to="/auth/login" class="btn btn-outline-success w-100 btn-sm ">ورود</nuxt-link>
<div class="form-group">
<button :disabled="params.loading" type="submit"
class="form-control btn btn-primary rounded submit px-3">
<span v-if="!params.loading">ثبت نام</span>
<div v-else class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</button>
</div>
</div>
<div
class="form-group d-flex flex-column flex-md-row mt-2 pt-2 justify-content-md-end gap-3 align-items-md-center">
<div>
<nuxt-link to="/auth/forgot-password" class="btn btn-outline-danger w-100 btn-sm ">بازیابی کلمه عبور
</nuxt-link>
</div>
<div>
<nuxt-link to="/auth/login" class="btn btn-outline-success w-100 btn-sm ">ورود</nuxt-link>
</div>
</div>
</section>
</form>
</div>
</div>
Expand All @@ -62,23 +94,23 @@ useHead({
// reflects form parameters
const params = reactive({
identity: null,
password: null,
loading: false,
showNextSteps: false,
})
// reflects the validation errors to corresponding html input.
const errors = reactive({
identity: null,
password: null,
})
async function login() {
async function register() {
try {
params.loading = true
await useAuth().login(params.identity, params.password)
await useAuth().register(params.identity)
params.showNextSteps = true
} catch (error) {
console.log(error)
errors.identity = "نام کاربری یا کلمه عبور اشتباه است"
errors.identity = "شما قبلا ثبت نام کرده اید"
}
params.loading = false
Expand Down
2 changes: 1 addition & 1 deletion frontend/pages/auth/reset-password.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
&nbsp;
<span>وارد حساب کاربری خود شوید </span>
</p>
<button :disabled="params.loading" type="submit"
<button :disabled="params.loading || params.succeed" type="submit"
class="form-control btn btn-primary rounded submit px-3">
<span v-if="!params.loading">ذخیره کن</span>
<div v-else class="spinner-border" role="status">
Expand Down
Loading

0 comments on commit 9719b2a

Please sign in to comment.