@@ -22,8 +25,12 @@
links: [
{
text: 'Sortilèges',
- url: '/spells',
+ url: '/sorts',
},
+ {
+ text: 'Écoles',
+ url: '/ecoles',
+ }
]
}
}
diff --git a/client/src/components/spells/spell-card.vue b/client/src/components/spells/spell-card.vue
index 27bbbae..2ae4a13 100644
--- a/client/src/components/spells/spell-card.vue
+++ b/client/src/components/spells/spell-card.vue
@@ -5,7 +5,7 @@
-
{{spell.name}}
+
{{spell.name}}
diff --git a/client/src/pages/index-page.vue b/client/src/pages/index-page.vue
index c2a1451..ee8a352 100644
--- a/client/src/pages/index-page.vue
+++ b/client/src/pages/index-page.vue
@@ -13,7 +13,7 @@
diff --git a/client/src/pages/schools/schools-page.vue b/client/src/pages/schools/schools-page.vue
new file mode 100644
index 0000000..34fc10a
--- /dev/null
+++ b/client/src/pages/schools/schools-page.vue
@@ -0,0 +1,15 @@
+
+
+
Écoles
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/pages/schools/single-school-page.vue b/client/src/pages/schools/single-school-page.vue
index 6681379..4dc4f8e 100644
--- a/client/src/pages/schools/single-school-page.vue
+++ b/client/src/pages/schools/single-school-page.vue
@@ -1,9 +1,9 @@
-
-
{{ school.name }}
-
{{ school.description }}
-
-
+
+
{{ school.name }}
+
{{ school.description }}
+
+
-
-
\ No newline at end of file
diff --git a/client/src/pages/spells/single-spell-page.vue b/client/src/pages/spells/single-spell-page.vue
new file mode 100644
index 0000000..dbaf519
--- /dev/null
+++ b/client/src/pages/spells/single-spell-page.vue
@@ -0,0 +1,15 @@
+
+
+
Sortilège
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/pages/spells/spells-page.vue b/client/src/pages/spells/spells-page.vue
new file mode 100644
index 0000000..91388ae
--- /dev/null
+++ b/client/src/pages/spells/spells-page.vue
@@ -0,0 +1,19 @@
+
+
+
Sortilèges
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/pages/user/login-page.vue b/client/src/pages/user/login-page.vue
new file mode 100644
index 0000000..111a7ba
--- /dev/null
+++ b/client/src/pages/user/login-page.vue
@@ -0,0 +1,15 @@
+
+
+
Connexion
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/routes.js b/client/src/routes.js
index c74327c..d3480a5 100644
--- a/client/src/routes.js
+++ b/client/src/routes.js
@@ -1,7 +1,13 @@
// Pages
-import Index from "./pages/index-page";
-import Spells from "./pages/spells-page";
-import SchoolSingle from "./pages/schools/single-school-page";
+import Index from "~/pages/index-page"
+
+import Spells from "~/pages/spells/spells-page"
+import SpellSingle from "~/pages/spells/single-spell-page"
+
+import Schools from "./pages/schools/schools-page"
+import SchoolSingle from "~/pages/schools/single-school-page"
+
+import Login from "~/pages/user/login-page"
// Routes
const routes = [
@@ -12,11 +18,20 @@ const routes = [
path: '/', component: Index,
},
{
- path: '/spells', component: Spells,
+ path: '/sorts', component: Spells,
},
{
- path: '/school/:id', component: SchoolSingle, props: true
- }
+ path: '/sorts/:id', component: SpellSingle, props: true,
+ },
+ {
+ path: '/ecoles', component: Schools,
+ },
+ {
+ path: '/ecoles/:id', component: SchoolSingle, props: true,
+ },
+ {
+ path: '/connexion', component: Login,
+ },
];
export default routes;
\ No newline at end of file
From ba89dc8c5ef89979367e8806c997b03bd830e152 Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Sat, 4 Jul 2020 23:07:52 +0200
Subject: [PATCH 20/31] - Added login method for users
---
repositories/user-repository.js | 74 +++++++++++++++++++++++++--------
routes/users.js | 24 +++++++++++
2 files changed, 80 insertions(+), 18 deletions(-)
diff --git a/repositories/user-repository.js b/repositories/user-repository.js
index a93d034..e1a6d2e 100644
--- a/repositories/user-repository.js
+++ b/repositories/user-repository.js
@@ -52,13 +52,13 @@ class UserRepository {
})
}
- getOneByEmail(mail) {
+ getOneByEmail(mail, full) {
return new Promise((resolve, reject) => {
model.forge()
- .where({ 'mail': mail})
+ .where({ 'mail': mail })
.fetch()
.then(v => {
- resolve(v.toJSON({ omitPivot: true }))
+ resolve(v.toJSON({ omitPivot: true, visibility: !full }))
})
.catch(err => {
reject(new HttpError(500, "Couldn't get user"))
@@ -66,18 +66,6 @@ class UserRepository {
})
}
- checkIfEmailAvailable(mail) {
- return new Promise((resolve, reject) => {
- this.getOneByEmail(mail)
- .then(() => {
- reject(false)
- })
- .catch(() => {
- resolve(true)
- })
- })
- }
-
addOne(u) {
return new Promise(async (resolve, reject) => {
// Checks if body exists and if the model fits, and throws errors if it doesn't
@@ -104,11 +92,21 @@ class UserRepository {
transacting: t
})
.catch(err => {
- console.log(err)
+ throw err
})
})
- .then(v => {
- resolve(this.getOneByUUID(uuid))
+ .then(() => {
+ return this.getOneByUUID(uuid)
+ })
+ .then(newUser => {
+ resolve({
+ "message": "Account successfully created !",
+ "data": {
+ "uuid": newUser.uuid,
+ "name": newUser.name,
+ "mail": newUser.mail,
+ },
+ })
})
.catch(err => {
throw err
@@ -120,6 +118,46 @@ class UserRepository {
}
})
}
+
+ // Log user with an email address and a password
+ logUser(mail, password) {
+ return new Promise((resolve, reject) => {
+ this.getOneByEmail(mail, true)
+ .then(async fetchedUser => {
+ let match = await bcrypt.compare(password, fetchedUser.password)
+ if (match) {
+ resolve({
+ "message": "User successfully logged in !",
+ "logged?": true,
+ "data": {
+ "uuid": fetchedUser.uuid
+ },
+ })
+ } else {
+ resolve({
+ "message": "The email and passwords don't match",
+ "logged?": false,
+ })
+ }
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+ }
+
+ // Check if one user already has that email
+ checkIfEmailAvailable(mail) {
+ return new Promise((resolve, reject) => {
+ this.getOneByEmail(mail, false)
+ .then(() => {
+ reject(false)
+ })
+ .catch(() => {
+ resolve(true)
+ })
+ })
+ }
}
module.exports = UserRepository
\ No newline at end of file
diff --git a/routes/users.js b/routes/users.js
index c6af63d..6219953 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -63,6 +63,30 @@ router.get('/:uuid/', async (req, res) => {
})
+// LOG A USER ------------------
+const logUser = (mail, password) => {
+ return Users.logUser(mail, password)
+ .catch(err => {
+ console.log(err)
+ throw err
+ })
+}
+router.post('/login', async (req, res) => {
+ logUser(req.body.mail, req.body.password)
+ .then(v => {
+ res.setHeader('Content-Type', 'application/json;charset=utf-8')
+ res.end(JSON.stringify(v))
+ })
+ .catch(err => {
+ res.status(err.code).send(JSON.stringify(
+ {
+ "error": err.message,
+ "code": err.code
+ })
+ )
+ })
+})
+
// CREATE ONE ------------------
const addUser = (u) => {
return Users.addOne(u)
From 4779e9d25ec64fd560811641ee2738490f1336e8 Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Sun, 5 Jul 2020 21:19:46 +0200
Subject: [PATCH 21/31] - Reworked some error handling and polished messages
for users
---
repositories/user-repository.js | 77 ++++++++++++++++++++-------------
1 file changed, 47 insertions(+), 30 deletions(-)
diff --git a/repositories/user-repository.js b/repositories/user-repository.js
index e1a6d2e..6bd5174 100644
--- a/repositories/user-repository.js
+++ b/repositories/user-repository.js
@@ -17,9 +17,6 @@ v.addSchema(UserValidation, "/UserValidation")
const isXSSAttempt = require('../functions').isXSSAttempt
const isEmptyObject = require('../functions').isEmptyObject
-// Error handling
-const { HttpError } = require('../validations/Errors')
-
class UserRepository {
constructor() {
@@ -32,22 +29,28 @@ class UserRepository {
.then(v => {
resolve(v.toJSON({ omitPivot: true }))
})
- .catch(err => {
- reject(new HttpError(500, "Couldn't get users"))
+ .catch(() => {
+ reject({
+ "message": "Database error, couldn't get all users.",
+ "code": 500
+ })
})
})
}
- getOneByUUID(uuid) {
+ getOneByUUID(uuid, full) {
return new Promise((resolve, reject) => {
model.forge()
.where({ 'uuid' : uuid })
.fetch()
.then(v => {
- resolve(v.toJSON({ omitPivot: true }))
+ resolve(v.toJSON({ omitPivot: true, visibility: !full }))
})
.catch(err => {
- reject(new HttpError(500, "Couldn't get user"))
+ reject({
+ "message": "User with this UUID was not found.",
+ "code": 404
+ })
})
})
}
@@ -60,8 +63,11 @@ class UserRepository {
.then(v => {
resolve(v.toJSON({ omitPivot: true, visibility: !full }))
})
- .catch(err => {
- reject(new HttpError(500, "Couldn't get user"))
+ .catch(() => {
+ reject({
+ "message": "User with this email was not found.",
+ "code": 404
+ })
})
})
}
@@ -70,11 +76,20 @@ class UserRepository {
return new Promise(async (resolve, reject) => {
// Checks if body exists and if the model fits, and throws errors if it doesn't
if (isEmptyObject(u)) {
- reject(new HttpError(403, "Error: User cannot be nothing !"))
+ reject({
+ "message": "Request body cannot be empty.",
+ "code": 403
+ })
} else if (!v.validate(u, UserValidation).valid) {
- reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(u, UserValidation).errors))
+ reject({
+ "message": "Schema is not valid - " + v.validate(u, UserValidation).errors,
+ "code": 403
+ })
} else if (isXSSAttempt(u.name) || isXSSAttempt(u.password) || isXSSAttempt(u.mail)) {
- reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
+ reject({
+ "message": "Injection attempt detected, aborting the request.",
+ "code": 403
+ })
} else {
let hash = await bcrypt.hash(u.password, 10)
let uuid = uuidv4()
@@ -96,24 +111,23 @@ class UserRepository {
})
})
.then(() => {
- return this.getOneByUUID(uuid)
+ return this.getOneByUUID(uuid, false)
})
.then(newUser => {
resolve({
"message": "Account successfully created !",
- "data": {
- "uuid": newUser.uuid,
- "name": newUser.name,
- "mail": newUser.mail,
- },
+ "user": newUser,
})
})
.catch(err => {
- throw err
+ resolve({
+ "message": "An error has occured while creating your account.",
+ "code": 500,
+ })
})
})
- .catch(() => {
- reject(new HttpError(403, 'Email is already in use !'))
+ .catch(err => {
+ reject(err)
})
}
})
@@ -124,19 +138,19 @@ class UserRepository {
return new Promise((resolve, reject) => {
this.getOneByEmail(mail, true)
.then(async fetchedUser => {
+
let match = await bcrypt.compare(password, fetchedUser.password)
+ delete fetchedUser.id
+ delete fetchedUser.password
+
if (match) {
resolve({
"message": "User successfully logged in !",
- "logged?": true,
- "data": {
- "uuid": fetchedUser.uuid
- },
+ "user": fetchedUser,
})
} else {
- resolve({
- "message": "The email and passwords don't match",
- "logged?": false,
+ reject({
+ "message": "The email and passwords don't match.",
})
}
})
@@ -151,7 +165,10 @@ class UserRepository {
return new Promise((resolve, reject) => {
this.getOneByEmail(mail, false)
.then(() => {
- reject(false)
+ reject({
+ "message": "Email is already in use !",
+ "code": 403
+ })
})
.catch(() => {
resolve(true)
From 0a4a59f6e66474161d2bfd0cac18cca64dabe722 Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Sun, 5 Jul 2020 21:48:49 +0200
Subject: [PATCH 22/31] - Added pages for register and scoped styles
---
client/src/assets/scss/_global.scss | 8 ++++
.../src/components/global/navbar/navbar.vue | 3 +-
client/src/pages/index-page.vue | 45 ++++++++-----------
client/src/pages/user/login-page.vue | 24 +++++++---
client/src/pages/user/register-page.vue | 25 +++++++++++
client/src/routes.js | 4 ++
6 files changed, 75 insertions(+), 34 deletions(-)
create mode 100644 client/src/pages/user/register-page.vue
diff --git a/client/src/assets/scss/_global.scss b/client/src/assets/scss/_global.scss
index 6c57871..dea2e02 100644
--- a/client/src/assets/scss/_global.scss
+++ b/client/src/assets/scss/_global.scss
@@ -49,4 +49,12 @@ hr {
border-top-style: solid;
border-top-width: 1px;
border-top-color: rgba($black, .25);
+}
+
+// LAYOUTS
+.fullpage {
+ min-height: calc(100vh - 56px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
\ No newline at end of file
diff --git a/client/src/components/global/navbar/navbar.vue b/client/src/components/global/navbar/navbar.vue
index 0ad8807..db97f88 100644
--- a/client/src/components/global/navbar/navbar.vue
+++ b/client/src/components/global/navbar/navbar.vue
@@ -11,7 +11,8 @@
- Connexion
+ S'inscrire
+ Se connecter
diff --git a/client/src/pages/index-page.vue b/client/src/pages/index-page.vue
index ee8a352..0100af5 100644
--- a/client/src/pages/index-page.vue
+++ b/client/src/pages/index-page.vue
@@ -1,14 +1,14 @@
-
\ No newline at end of file
diff --git a/client/src/pages/user/login-page.vue b/client/src/pages/user/login-page.vue
index 111a7ba..2f4bb2f 100644
--- a/client/src/pages/user/login-page.vue
+++ b/client/src/pages/user/login-page.vue
@@ -1,15 +1,25 @@
-
-
Connexion
+
-
\ No newline at end of file
diff --git a/client/src/pages/user/register-page.vue b/client/src/pages/user/register-page.vue
new file mode 100644
index 0000000..d254b84
--- /dev/null
+++ b/client/src/pages/user/register-page.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/routes.js b/client/src/routes.js
index d3480a5..b442e0a 100644
--- a/client/src/routes.js
+++ b/client/src/routes.js
@@ -8,6 +8,7 @@ import Schools from "./pages/schools/schools-page"
import SchoolSingle from "~/pages/schools/single-school-page"
import Login from "~/pages/user/login-page"
+import Register from "~/pages/user/register-page"
// Routes
const routes = [
@@ -32,6 +33,9 @@ const routes = [
{
path: '/connexion', component: Login,
},
+ {
+ path: '/inscription', component: Register,
+ },
];
export default routes;
\ No newline at end of file
From 78587f8544cd6ae6498963b0943deb58baec20ee Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Mon, 6 Jul 2020 12:49:09 +0200
Subject: [PATCH 23/31] - Added basic user login
---
client/package-lock.json | 5 ++
client/package.json | 1 +
client/src/api/repositories.js | 2 +
client/src/api/usersRepository.js | 12 ++++
.../src/components/global/navbar/navbar.vue | 1 +
client/src/main.js | 20 +++---
client/src/pages/user/login-page.vue | 53 ++++++++++++++-
client/src/pages/user/profile-page.vue | 25 ++++++++
client/src/routes.js | 64 ++++++++++++++++---
9 files changed, 161 insertions(+), 22 deletions(-)
create mode 100644 client/src/api/usersRepository.js
create mode 100644 client/src/pages/user/profile-page.vue
diff --git a/client/package-lock.json b/client/package-lock.json
index e53b9cb..8aa7da7 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -11960,6 +11960,11 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
},
+ "vue-cookies": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.7.0.tgz",
+ "integrity": "sha512-vuEUm6wYMMrFAHFCrkzIUAy8+MgPAbBGmYXnk2M6X6O2KHbMT1wuDD2izacmsSUp6ZM02e23MJRtPRobl88VMg=="
+ },
"vue-eslint-parser": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.0.0.tgz",
diff --git a/client/package.json b/client/package.json
index dea18a1..1cd78c3 100644
--- a/client/package.json
+++ b/client/package.json
@@ -35,6 +35,7 @@
"popper.js": "^1.16.1",
"v-clipboard": "^2.2.3",
"vue": "^2.6.11",
+ "vue-cookies": "^1.7.0",
"vue-masonry": "^0.11.8"
},
"devDependencies": {
diff --git a/client/src/api/repositories.js b/client/src/api/repositories.js
index a663bfa..96fddd7 100644
--- a/client/src/api/repositories.js
+++ b/client/src/api/repositories.js
@@ -3,6 +3,7 @@ import schoolsRepository from './schoolsRepository'
import metaschoolsRepository from './metaschoolsRepository'
import variablesRepository from './variablesRepository'
import ingredientsRepository from './ingredientsRepository'
+import usersRepository from './usersRepository'
// List of possible repositories
const repositories = {
@@ -11,6 +12,7 @@ const repositories = {
metaschools: metaschoolsRepository,
variables: variablesRepository,
ingredients: ingredientsRepository,
+ users: usersRepository,
}
// Usage : RepositoryFactoryInstance.get('reponame');
diff --git a/client/src/api/usersRepository.js b/client/src/api/usersRepository.js
new file mode 100644
index 0000000..9320855
--- /dev/null
+++ b/client/src/api/usersRepository.js
@@ -0,0 +1,12 @@
+import api from './api'
+
+const resource = "/users"
+
+export default {
+ login(data) {
+ return api.post(`${resource}/login`, data)
+ },
+ addOne(data) {
+ return api.post(`${resource}`, data)
+ },
+}
\ No newline at end of file
diff --git a/client/src/components/global/navbar/navbar.vue b/client/src/components/global/navbar/navbar.vue
index db97f88..20b899c 100644
--- a/client/src/components/global/navbar/navbar.vue
+++ b/client/src/components/global/navbar/navbar.vue
@@ -11,6 +11,7 @@
+ Profil
S'inscrire
Se connecter
diff --git a/client/src/main.js b/client/src/main.js
index 9f46591..d4de66a 100644
--- a/client/src/main.js
+++ b/client/src/main.js
@@ -8,9 +8,13 @@ Globals.forEach(component => {
Vue.component(component.name, component)
});
-// Auth
+// Environment
require('dotenv').config()
+// Cookies
+import VueCookies from 'vue-cookies'
+Vue.use(VueCookies)
+
// Jquery
import jquery from 'jquery'
window.$ = jquery
@@ -26,7 +30,7 @@ import 'bootstrap/dist/js/bootstrap.js'
import { BootstrapVue } from 'bootstrap-vue'
Vue.use(BootstrapVue)
-import { VueMasonryPlugin } from 'vue-masonry';
+import { VueMasonryPlugin } from 'vue-masonry'
Vue.use(VueMasonryPlugin)
import clipboard from 'v-clipboard'
@@ -39,18 +43,12 @@ var filter = function(text, length, clamp){
node.innerHTML = text;
var content = node.textContent;
return content.length > length ? content.slice(0, length) + clamp : content;
-};
-Vue.filter('truncate', filter);
+}
+Vue.filter('truncate', filter)
// Router
-import routes from './routes'
+import router from './routes'
Vue.use(VueRouter)
-const router = new VueRouter({
- mode: 'history',
- routes,
- linkActiveClass: "",
- linkExactActiveClass: "active",
-});
// Mount Vue
const app = new Vue({
diff --git a/client/src/pages/user/login-page.vue b/client/src/pages/user/login-page.vue
index 2f4bb2f..e2db8f0 100644
--- a/client/src/pages/user/login-page.vue
+++ b/client/src/pages/user/login-page.vue
@@ -1,14 +1,65 @@
diff --git a/client/src/pages/user/profile-page.vue b/client/src/pages/user/profile-page.vue
new file mode 100644
index 0000000..944eb37
--- /dev/null
+++ b/client/src/pages/user/profile-page.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/routes.js b/client/src/routes.js
index b442e0a..8ca8eaa 100644
--- a/client/src/routes.js
+++ b/client/src/routes.js
@@ -1,3 +1,6 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+
// Pages
import Index from "~/pages/index-page"
@@ -9,33 +12,74 @@ import SchoolSingle from "~/pages/schools/single-school-page"
import Login from "~/pages/user/login-page"
import Register from "~/pages/user/register-page"
+import Profile from "~/pages/user/profile-page"
// Routes
const routes = [
{
- path: "*", redirect: "/",
+ path: "*",
+ redirect: "/",
},
{
- path: '/', component: Index,
+ path: '/',
+ component: Index,
},
{
- path: '/sorts', component: Spells,
+ path: '/connexion',
+ component: Login,
},
{
- path: '/sorts/:id', component: SpellSingle, props: true,
+ path: '/inscription',
+ component: Register,
},
{
- path: '/ecoles', component: Schools,
+ path: '/sorts',
+ component: Spells,
},
{
- path: '/ecoles/:id', component: SchoolSingle, props: true,
+ path: '/sorts/:id',
+ component: SpellSingle,
+ props: true,
},
{
- path: '/connexion', component: Login,
+ path: '/ecoles',
+ component: Schools,
},
{
- path: '/inscription', component: Register,
+ path: '/ecoles/:id',
+ component: SchoolSingle,
+ props: true,
},
-];
+ {
+ path: '/profil',
+ component: Profile,
+ props: true,
+ meta: {
+ authGuard: true,
+ }
+ },
+]
-export default routes;
\ No newline at end of file
+const router = new VueRouter({
+ mode: 'history',
+ routes,
+ linkActiveClass: "",
+ linkExactActiveClass: "active",
+})
+
+router.beforeEach((to, from, next) => {
+ if (to.matched.some(record => record.meta.authGuard)) {
+ if (Vue.$cookies.get('loggedUser') == null) {
+ next({
+ path: '/connexion',
+ params: { nextUrl: to.fullPath }
+ })
+ } else {
+ next()
+ }
+ } else {
+ next()
+ }
+})
+
+export default router;
\ No newline at end of file
From 27ab62e36fcbe901d3ef30c864190f65c8c4461b Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Mon, 6 Jul 2020 18:24:54 +0200
Subject: [PATCH 24/31] - Added login check for navbar actions
---
client/src/components/global/navbar/navbar.vue | 8 ++++++--
client/src/main.js | 1 +
client/src/pages/user/login-page.vue | 3 +--
client/src/pages/user/profile-page.vue | 11 +++++++----
client/src/routes.js | 4 ++--
package.json | 3 ++-
6 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/client/src/components/global/navbar/navbar.vue b/client/src/components/global/navbar/navbar.vue
index 20b899c..99f0d9a 100644
--- a/client/src/components/global/navbar/navbar.vue
+++ b/client/src/components/global/navbar/navbar.vue
@@ -10,10 +10,13 @@
{{ link.text }}
-
+
Profil
+ Deconnexion
+
+
S'inscrire
- Se connecter
+ Connexion
@@ -24,6 +27,7 @@
name: 'navbar',
data() {
return {
+ user: this.$cookies.get("U_"),
links: [
{
text: 'Sortilèges',
diff --git a/client/src/main.js b/client/src/main.js
index d4de66a..c5f47a7 100644
--- a/client/src/main.js
+++ b/client/src/main.js
@@ -14,6 +14,7 @@ require('dotenv').config()
// Cookies
import VueCookies from 'vue-cookies'
Vue.use(VueCookies)
+Vue.$cookies.config('30d','','')
// Jquery
import jquery from 'jquery'
diff --git a/client/src/pages/user/login-page.vue b/client/src/pages/user/login-page.vue
index e2db8f0..b201808 100644
--- a/client/src/pages/user/login-page.vue
+++ b/client/src/pages/user/login-page.vue
@@ -52,8 +52,7 @@ export default {
"password": this.password
})
.then(v => {
- let user = v.data
- this.$cookies.set("loggedUser", user, 60 * 60 * 24 * 30)
+ this.$cookies.set("U_", v.data.user, 60 * 60 * 24 * 30)
})
.catch(err => {
console.log(err)
diff --git a/client/src/pages/user/profile-page.vue b/client/src/pages/user/profile-page.vue
index 944eb37..b24c702 100644
--- a/client/src/pages/user/profile-page.vue
+++ b/client/src/pages/user/profile-page.vue
@@ -1,14 +1,17 @@
-
-
+
+
{{ user.name }}
diff --git a/client/src/routes.js b/client/src/routes.js
index 8ca8eaa..e19646a 100644
--- a/client/src/routes.js
+++ b/client/src/routes.js
@@ -69,10 +69,10 @@ const router = new VueRouter({
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.authGuard)) {
- if (Vue.$cookies.get('loggedUser') == null) {
+ if (Vue.$cookies.get('U_') == null) {
next({
path: '/connexion',
- params: { nextUrl: to.fullPath }
+ params: { nextUrl: to.fullPath },
})
} else {
next()
diff --git a/package.json b/package.json
index 0e4bf54..f93fffe 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,8 @@
"description": "API for Auracle database",
"main": "index.js",
"scripts": {
- "test": "start"
+ "api": "node index.js",
+ "client": "cd client && npm run serve"
},
"repository": {
"type": "git",
From 9b10cd473e4ddb68ac69ac92529eb104cdb44bae Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Mon, 6 Jul 2020 21:22:03 +0200
Subject: [PATCH 25/31] - Implemented store and logged states
---
client/package-lock.json | 5 +++
client/package.json | 3 +-
client/src/assets/scss/_global.scss | 5 +++
.../src/components/global/navbar/navbar.vue | 19 ++++++++--
client/src/main.js | 36 ++++++++++++++++++-
client/src/pages/user/login-page.vue | 6 +++-
6 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/client/package-lock.json b/client/package-lock.json
index 8aa7da7..0103e23 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -12073,6 +12073,11 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
+ "vuex": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
+ "integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
+ },
"watchpack": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
diff --git a/client/package.json b/client/package.json
index 1cd78c3..b68acd3 100644
--- a/client/package.json
+++ b/client/package.json
@@ -36,7 +36,8 @@
"v-clipboard": "^2.2.3",
"vue": "^2.6.11",
"vue-cookies": "^1.7.0",
- "vue-masonry": "^0.11.8"
+ "vue-masonry": "^0.11.8",
+ "vuex": "^3.5.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.2.0",
diff --git a/client/src/assets/scss/_global.scss b/client/src/assets/scss/_global.scss
index dea2e02..8968aae 100644
--- a/client/src/assets/scss/_global.scss
+++ b/client/src/assets/scss/_global.scss
@@ -51,6 +51,11 @@ hr {
border-top-color: rgba($black, .25);
}
+// BOOTSTRAP
+.nav-link {
+ cursor: pointer;
+}
+
// LAYOUTS
.fullpage {
min-height: calc(100vh - 56px);
diff --git a/client/src/components/global/navbar/navbar.vue b/client/src/components/global/navbar/navbar.vue
index 99f0d9a..8a8a473 100644
--- a/client/src/components/global/navbar/navbar.vue
+++ b/client/src/components/global/navbar/navbar.vue
@@ -10,9 +10,9 @@
{{ link.text }}
-
+
Profil
-
Deconnexion
+
Deconnexion
S'inscrire
@@ -27,7 +27,6 @@
name: 'navbar',
data() {
return {
- user: this.$cookies.get("U_"),
links: [
{
text: 'Sortilèges',
@@ -39,6 +38,20 @@
}
]
}
+ },
+ computed: {
+ loggedIn() {
+ return this.$store.state.status.loggedIn;
+ }
+ },
+ methods: {
+ logoutUser() {
+ if (this.$cookies.get('U_') != null) {
+ this.$cookies.remove('U_')
+ this.$store.commit('logout')
+ this.$router.push('/')
+ }
+ }
}
}
diff --git a/client/src/main.js b/client/src/main.js
index c5f47a7..53d4b91 100644
--- a/client/src/main.js
+++ b/client/src/main.js
@@ -1,5 +1,6 @@
// Core
import Vue from 'vue'
+import Vuex from 'vuex'
import VueRouter from 'vue-router'
import App from './app.vue'
@@ -51,9 +52,42 @@ Vue.filter('truncate', filter)
import router from './routes'
Vue.use(VueRouter)
+// Store
+Vue.use(Vuex)
+let user = Vue.$cookies.get('U_')
+
+const store = new Vuex.Store({
+ state: user ?
+ { status: { loggedIn: true }, user }
+ : { status: { loggedIn: false }, user: null },
+ mutations: {
+ loginSucceed (state, user) {
+ state.status.loggedIn = true
+ state.user = user
+ },
+ loginFail (state) {
+ state.status.loggedIn = false
+ state.user = null
+ },
+ logout(state) {
+ state.status.loggedIn = false;
+ state.user = null;
+ },
+ registerSucceed (state, user) {
+ state.status.loggedIn = true
+ state.user = user
+ },
+ registerFail (state) {
+ state.status.loggedIn = false
+ state.user = null
+ },
+ }
+})
+
// Mount Vue
const app = new Vue({
render: h => h(App),
- router
+ router,
+ store: store
})
app.$mount('#srs')
diff --git a/client/src/pages/user/login-page.vue b/client/src/pages/user/login-page.vue
index b201808..5aa5499 100644
--- a/client/src/pages/user/login-page.vue
+++ b/client/src/pages/user/login-page.vue
@@ -52,9 +52,13 @@ export default {
"password": this.password
})
.then(v => {
- this.$cookies.set("U_", v.data.user, 60 * 60 * 24 * 30)
+ let user = v.data.user
+ this.$cookies.set("U_", user, 60 * 60 * 24 * 30)
+ this.$store.commit('loginSucceed', user)
+ this.$router.push('/profil')
})
.catch(err => {
+ this.$store.commit('loginFailed')
console.log(err)
})
}
From 080c46593ca5f3d2e1a696c4146e4eafb3c166e9 Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Tue, 7 Jul 2020 23:24:10 +0200
Subject: [PATCH 26/31] - Added error handler to register form
---
client/src/api/usersRepository.js | 2 +-
client/src/assets/scss/_global.scss | 4 +
.../src/components/global/navbar/navbar.vue | 5 +-
client/src/pages/index-page.vue | 19 ++-
client/src/pages/user/login-page.vue | 31 ++--
client/src/pages/user/register-page.vue | 146 +++++++++++++++++-
client/src/routes.js | 6 +
repositories/user-repository.js | 4 +-
8 files changed, 191 insertions(+), 26 deletions(-)
diff --git a/client/src/api/usersRepository.js b/client/src/api/usersRepository.js
index 9320855..2e041a9 100644
--- a/client/src/api/usersRepository.js
+++ b/client/src/api/usersRepository.js
@@ -6,7 +6,7 @@ export default {
login(data) {
return api.post(`${resource}/login`, data)
},
- addOne(data) {
+ register(data) {
return api.post(`${resource}`, data)
},
}
\ No newline at end of file
diff --git a/client/src/assets/scss/_global.scss b/client/src/assets/scss/_global.scss
index 8968aae..37fcf93 100644
--- a/client/src/assets/scss/_global.scss
+++ b/client/src/assets/scss/_global.scss
@@ -56,6 +56,10 @@ hr {
cursor: pointer;
}
+.btn {
+ margin-right: 5px;
+}
+
// LAYOUTS
.fullpage {
min-height: calc(100vh - 56px);
diff --git a/client/src/components/global/navbar/navbar.vue b/client/src/components/global/navbar/navbar.vue
index 8a8a473..85ec442 100644
--- a/client/src/components/global/navbar/navbar.vue
+++ b/client/src/components/global/navbar/navbar.vue
@@ -10,12 +10,11 @@
{{ link.text }}
-
+
-
diff --git a/client/src/pages/index-page.vue b/client/src/pages/index-page.vue
index 0100af5..3018784 100644
--- a/client/src/pages/index-page.vue
+++ b/client/src/pages/index-page.vue
@@ -1,12 +1,12 @@
-
-
+
+
"C'est magique, ta gueule."
— N'importe quel MJ, une fois dans sa vie
Auracle est une base de données publique en ligne pour sortilèges, en soutien au jeu de rôle sur table Leïm.
-
+
@@ -18,9 +18,16 @@ export default {
\ No newline at end of file
diff --git a/client/public/libs/material-design-icons.woff2 b/client/src/assets/fonts/material-design-icons.woff2
similarity index 100%
rename from client/public/libs/material-design-icons.woff2
rename to client/src/assets/fonts/material-design-icons.woff2
diff --git a/client/public/img/bg1.png b/client/src/assets/images/bg1.png
similarity index 100%
rename from client/public/img/bg1.png
rename to client/src/assets/images/bg1.png
diff --git a/client/src/assets/scss/_fonts.scss b/client/src/assets/scss/_fonts.scss
index e69de29..c533377 100644
--- a/client/src/assets/scss/_fonts.scss
+++ b/client/src/assets/scss/_fonts.scss
@@ -0,0 +1,36 @@
+
+.font-display{ font-family: 'Playfair Display', serif; }
+.font-weight-100{ font-weight: 100; }
+.font-weight-200{ font-weight: 200; }
+.font-weight-300{ font-weight: 300; }
+.font-weight-400{ font-weight: 400; }
+.font-weight-500{ font-weight: 500; }
+.font-weight-600{ font-weight: 600; }
+.font-weight-700{ font-weight: 700; }
+.font-weight-800{ font-weight: 800; }
+.font-weight-900{ font-weight: 900; }
+
+.line-height-100{ line-height: 100%; }
+
+@font-face{
+ font-family: 'Material Icons';
+ font-style: normal;
+ font-weight: 400;
+ src: url('../fonts/material-design-icons.woff2') format('woff2');
+}
+.mad {
+ font-family: 'Material Icons';
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ transform: translateY(12.5%);
+ letter-spacing: normal;
+ text-transform: none;
+ display: inline-block;
+ white-space: nowrap;
+ word-wrap: normal;
+ direction: ltr;
+ -webkit-font-feature-settings: 'liga';
+ font-feature-settings: 'liga';
+ -webkit-font-smoothing: antialiased;
+}
diff --git a/client/src/assets/scss/_global.scss b/client/src/assets/scss/_global.scss
index 37fcf93..3e38270 100644
--- a/client/src/assets/scss/_global.scss
+++ b/client/src/assets/scss/_global.scss
@@ -1,6 +1,5 @@
// Other global files
@import '_variables';
-@import '_mixins';
@import '_fonts';
// RESETS
@@ -13,29 +12,21 @@ html {
color: $primary--base;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-}
-
-html *,
-html *::before,
-html *::after {
- box-sizing: border-box;
-}
-
-* {
- margin: 0;
- padding: 0;
- outline: none;
+ * {
+ margin: 0;
+ padding: 0;
+ outline: none;
+ box-sizing: border-box;
+ &:before, &:after {
+ box-sizing: border-box;
+ }
+ }
}
@at-root {
@-ms-viewport { width: device-width; }
}
-a {
- text-decoration: none;
- color: inherit;
-}
-
ul {
list-style-type: none;
}
@@ -55,11 +46,13 @@ hr {
.nav-link {
cursor: pointer;
}
-
.btn {
margin-right: 5px;
}
+.word-break{ word-wrap: break-word; }
+.cursor-pointer{ cursor: pointer; }
+
// LAYOUTS
.fullpage {
min-height: calc(100vh - 56px);
diff --git a/client/src/assets/scss/_mixins.scss b/client/src/assets/scss/_mixins.scss
deleted file mode 100644
index 14f2386..0000000
--- a/client/src/assets/scss/_mixins.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-@mixin blue-glow-box($radius) {
- box-shadow: 0 0 .5rem * $radius #fff, 0 0 1rem * $radius $primary--blue, 0 0 2rem * $radius $primary--blue;
-}
-@mixin blue-glow-text($radius) {
- text-shadow: 0 0 .5rem * $radius #fff, 0 0 1rem * $radius $primary--blue, 0 0 2rem * $radius $primary--blue;
-}
\ No newline at end of file
diff --git a/client/src/pages/index-page.vue b/client/src/pages/index-page.vue
index 3018784..4774949 100644
--- a/client/src/pages/index-page.vue
+++ b/client/src/pages/index-page.vue
@@ -5,7 +5,7 @@
"C'est magique, ta gueule."
— N'importe quel MJ, une fois dans sa vie
-
Auracle est une base de données publique en ligne pour sortilèges, en soutien au jeu de rôle sur table Leïm.
+
Auracle est une base de données publique en ligne pour sortilèges, en soutien au jeu de rôle sur table Leïm.
@@ -24,9 +24,14 @@ section {
width: 1000px;
.title {
font-size: 5rem;
- font-weight: 700;
+ font-weight: 900;
text-align: center;
}
+ .lead {
+ .font-display {
+ font-weight: 700;
+ }
+ }
}
}
@media only screen and (max-width: 600px) {
From d2acdbb179fa524f4369cd2e015468550ed60751 Mon Sep 17 00:00:00 2001
From: Alexis <35.alexis.pele@gmail.com>
Date: Fri, 17 Jul 2020 21:20:42 +0200
Subject: [PATCH 29/31] - Removed useless stuff
---
client/public/index.html | 1 -
client/src/app.vue | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/client/public/index.html b/client/public/index.html
index cb43775..65749c0 100644
--- a/client/public/index.html
+++ b/client/public/index.html
@@ -8,7 +8,6 @@
Auracle
-