Compare commits

..

13 Commits

Author SHA1 Message Date
204e6a9505
Base oauth et spring sessions
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m0s
Build and test backend / Test-backend (pull_request) Successful in 1m55s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 20s
2024-03-07 15:24:22 +01:00
dbbf74f2c3 Merge pull request 'tonitch/front/User_API' (#56) from tonitch/front/User_API into master
All checks were successful
Build and test backend / Build-backend (push) Successful in 2m11s
Build and test backend / Test-backend (push) Successful in 1m22s
deploy to production / deploy-frontend (push) Successful in 22s
deploy to production / deploy-backend (push) Successful in 2m18s
Build and test FrontEnd / Build-frontend (push) Successful in 21s
Reviewed-on: #56
Reviewed-by: Maxime <231026@umons.ac.be>
Reviewed-by: Wal <karpinskiwal@gmail.com>
2024-03-07 14:12:49 +01:00
0e7c18e088 Base for rest api utilisation (#53)
All checks were successful
Build and test backend / Build-backend (push) Successful in 2m11s
Build and test backend / Test-backend (push) Successful in 1m23s
deploy to production / deploy-frontend (push) Successful in 23s
deploy to production / deploy-backend (push) Successful in 2m18s
Build and test FrontEnd / Build-frontend (push) Successful in 21s
The restConsumer will be the base, then I will create a js file per
"object" (for instance there will be users.js with all endpoints for
users using the restConsumer.js)

Reviewed-on: #53
Reviewed-by: Wal <karpinskiwal@gmail.com>
Reviewed-by: Maxime <231026@umons.ac.be>
Co-authored-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
Co-committed-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
2024-03-06 21:38:09 +01:00
6df81a66f2
Fixing i18n path
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m58s
Build and test backend / Test-backend (pull_request) Successful in 1m56s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 19s
Build and test backend / Build-backend (push) Successful in 2m5s
Build and test backend / Test-backend (push) Successful in 1m17s
deploy to production / deploy-frontend (push) Successful in 21s
deploy to production / deploy-backend (push) Successful in 2m17s
Build and test FrontEnd / Build-frontend (push) Successful in 20s
2024-03-06 14:41:03 +01:00
aaaba0ddf3
User api first draft finished
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m55s
Build and test backend / Test-backend (pull_request) Successful in 1m52s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 19s
2024-03-06 14:08:39 +01:00
e158fa1f87
backbone for login
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m58s
Build and test backend / Test-backend (pull_request) Successful in 1m52s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 32s
2024-03-06 09:00:55 +01:00
6289be529a
package-lock was forgoten 2024-03-06 08:59:08 +01:00
1f69040436
adding patch to restConsumer 2024-03-06 08:59:08 +01:00
56a14a3e8a
adding toast on requests 2024-03-06 08:59:06 +01:00
d1b4023d92
adding register 2024-03-05 14:58:56 +01:00
837db9aba9
backbone for login 2024-03-05 14:10:13 +01:00
09d5e1c293
Document rest
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m55s
Build and test backend / Test-backend (pull_request) Successful in 1m50s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 19s
2024-03-05 11:48:04 +01:00
8c2397c4cf
Base for rest api utilisation
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m54s
Build and test backend / Test-backend (pull_request) Successful in 1m52s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 20s
The restConsumer will be the base, then I will create a js file per
"object" (for instance there will be users.js with all endpoints for
users using the restConsumer.js)
2024-03-05 00:15:52 +01:00
9 changed files with 130 additions and 184 deletions

View File

@ -1,17 +1,8 @@
# English translations (some examples to remove) # English translations (some examples to remove)
login.guest.signin=Sign in login.guest.login=log in
login.guest.register=Register login.guest.register=register
login.guest.alregister=Already Registered login.guest.welcome=Please Register here
login.guest.welcome=WELCOME TO THE UNIVERSITY login.success=You are now registered as $name
login.guest.email=E-MAIL
login.guest.firstname= FIRSTNAME
login.guest.surname=SURNAME
login.guest.country=COUNTRY
login.guest.address=ADDRESS
login.guest.password=PASSWORD
login.guest.nextpage=Next Page
login.guest.lastpage=Last Page
login.guest.submit=Submit
#===================================================== #=====================================================

View File

@ -1,17 +1,8 @@
# Traductions françaises (Quelques examples a enlever) # Traductions françaises (Quelques examples a enlever)
login.guest.signin=SE CONNECTER login.guest.login=s'identifier
login.guest.register=S'enregistrer login.guest.register=s'enregistrer
login.guest.alregister=Déjà Enregistré login.guest.welcome=Veuillez vous enregistrer ici
login.guest.welcome=BIENVENUE A L'UNIVERSITE login.success=Vous êtes maintenant identifié comme $name
login.guest.email=E-MAIL
login.guest.firstname= PRENOM
login.guest.surname= NOM
login.guest.country= PAYS
login.guest.address=ADRESSE
login.guest.password= MOT DE PASSE
login.guest.nextpage=Prochaine Page
login.guest.lastpage=Derniere Page
login.guest.submit=Envoyer
#===================================================== #=====================================================

View File

@ -34,9 +34,9 @@
<div class="fa-solid fa-bell" style="margin-top: 7px; margin-bottom: 3px;"></div> <div class="fa-solid fa-bell" style="margin-top: 7px; margin-bottom: 3px;"></div>
</a></li> </a></li>
<li style="float: right;" title="Options"> <li style="float: right;" title="Options">
<div class="item"> <a href="#Options">
<div class="fa-solid fa-gear" style="margin-top: 7px; margin-bottom: 3px;"></div> <div class="fa-solid fa-gear" style="margin-top: 7px; margin-bottom: 3px;"></div>
</div></li> </a></li>
</ul> </ul>
</div> </div>
@ -112,7 +112,7 @@
transition-duration: .3s; transition-duration: .3s;
} }
.item,li a{ li a{
display: flex; display: flex;
padding: 8px 16px; padding: 8px 16px;
color:rgb(255, 255, 255); color:rgb(255, 255, 255);
@ -159,8 +159,7 @@
} }
ul.horizontal .item:hover, li a:hover:not(.active){ ul.horizontal li a:hover:not(.active){
background-color: black; background-color: black;
border-radius:6px; border-radius:6px;
color:white; color:white;

View File

@ -1,134 +1,39 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import i18n from './i18n.js' import { login } from './rest/Users.js'
const login= ref(true)
const page = ref(0) const username = ref("");
const password = ref("");
const emailID=ref("")
const passwordIN=ref("")
const surname=ref("")
const firstname=ref("")
const passwordOUT=ref("")
const emailOUT=ref("")
const address=ref("")
const country=ref("")
const cursus=ref("")
const inputs = [{_emailID:emailID},{_passwordIN:passwordIN}]
const outputs= [{_surname:surname},{_firstname:firstname},{_passwordOUT:passwordOUT},{_emailOUT:emailOUT},{_address:address},{_country:country},{_cursus:cursus}]
</script> </script>
<template> <template>
<body> <body>
<div class="Home">
<a href="/">
<img @click="draw" src="./assets/Clyde.png" style="width: 40px; height: auto; margin-top:4px">
</a>
</div>
<div class="logBoxCenterer"> <div class="logBoxCenterer">
<div class='loginBox'> <div class='loginBox'>
<form @submit.prevent="login(username, password)" class="form">
<div v-if="login"> <h1 style="color:rgb(239,60,168); font-family: sans-serif;">SIGN IN</h1>
<div class="form"> <div class="inputBox">
<h1 style="color:rgb(239,60,168); font-family: sans-serif;">{{i18n("login.guest.signin")}}</h1> <p>USERNAME</p>
<div class="inputBox"> <input v-model="username" type="text" required>
<p>ID / {{i18n("login.guest.email")}}</p>
<input type="text" v-model="emailID">
</div>
<div class="inputBox">
<p>{{i18n("login.guest.password")}}</p>
<input type="password" v-model="passwordIN">
</div>
<div class="register">
<a @click="login=!login">{{i18n("login.guest.register")}}</a>
</div>
<div class="inputBox">
<button @click="console.log(inputs)">{{i18n("login.guest.submit")}}</button>
</div>
</div>
</div> </div>
<div class="inputBox">
<div v-else> <p>PASSWORD</p>
<div class="form"> <input v-model=password type="password" required>
<h1 style="color:rgb(239,60,168); font-family: sans-serif; text-align:center;">{{i18n("login.guest.welcome")}}</h1>
<div v-if="page === 0">
<div class="inputBox">
<p>{{i18n("login.guest.surname")}}</p>
<input type="text" v-model="surname">
</div>
<div class="inputBox">
<p>{{i18n("login.guest.firstname")}}</p>
<input type="text" v-model="firstname">
</div>
<div class="inputBox">
<p>{{i18n("login.guest.password")}}</p>
<input type="password" v-model="passwordOUT">
</div>
<div class="inputBox">
<p>Cursus</p>
<select v-model="cursus">
<option value="Chemistry">Chemistry</option>
<option value="Psycho">Psychology</option>
<option value="IT">IT</option>
</select>
</div>
<div class="switchpage">
<button @click="page++">{{i18n("login.guest.nextpage")}}</button>
</div>
<div @click="(login=!login) && (page=0)" class="register">
<a>{{i18n("login.guest.alregister")}}</a>
</div>
</div>
<div v-else>
<div class="inputBox">
<p>{{i18n("login.guest.email")}}</p>
<input type="mail" v-model="emailOUT">
</div>
<div class="inputBox">
<p>{{i18n("login.guest.address")}}</p>
<input type="text" v-model="address">
</div>
<div class="inputBox">
<p>{{i18n("login.guest.country")}}</p>
<input type="text" v-model="country">
</div>
<div style="align-self:center;" class="inputBox">
<button style="margin-top:25px;" @click="console.log(outputs)">{{i18n("login.guest.submit")}}</button>
</div>
<div class="switchpage">
<button @click="page--">{{i18n("login.guest.lastpage")}}</button>
</div>
<div @click="(login=!login) && (page=0)" class="register">
<a>{{i18n("login.guest.alregister")}}</a>
</div>
</div>
</div> </div>
</div> <div class="register">
<a>Register</a>
</div>
<div class="inputBox">
<input type="submit" value="Login">
</div>
</form>
</div> </div>
</div> </div>
</body> </body>
</template> </template>
<style scoped> <style scoped>
.Home{
display: flex;
padding: 8px 16px;
color:rgb(255, 255, 255);
text-decoration: none;
}
.Home:hover{
width:40px;
background-color: black;
border-radius:6px;
color:white;
transform: translate(0px ,1px);
}
.logBoxCenterer { .logBoxCenterer {
position: absolute; position: absolute;
@ -162,8 +67,7 @@
} }
.inputBox input,button,select { .inputBox input {
width:100%; width:100%;
background:rgb(255, 0 255); background:rgb(255, 0 255);
border: none; border: none;
@ -188,36 +92,20 @@
.register{ .register{
color:rgb(239,60,168); color:rgb(239,60,168);
width: 100%; width: 100%;
align-items:center;
display:flex; display:flex;
justify-content: center;
cursor: pointer; cursor: pointer;
} }
.switchpage{ input[type = "submit"] {
width:100px;
background:rgb(255, 0 255);
border: none;
padding-right:0;
padding-top:10px;
padding-bottom:10px;
outline:none;
border-radius: 4px;
font-size:0.8em;
align-self:right;
}
button,select{
margin-bottom:20px;
background-color: rgb(239,60,168); background-color: rgb(239,60,168);
cursor: pointer; cursor: pointer;
padding:10px; padding:10px;
font-size:1.35em; font-size:1.35em;
border:none;
border-radius:20px;
} }
button:active ,.switchpage:active{ input[type = "submit"]:active{
opacity:0.8; opacity:0.8;
} }

View File

@ -9,6 +9,8 @@
* *
*/ */
import { getCookie } from './utils.js';
const default_lang = "EN"; const default_lang = "EN";
let langs; let langs;
@ -36,22 +38,6 @@ export default function i18n(key, options) {
// Those functions are utility functions use by previous exported functions. // Those functions are utility functions use by previous exported functions.
// //
/**
* Return the content of a cookie with specified key
* @param key cookie name
*/
function getCookie(key){
key = key + "="
let cookies = decodeURIComponent(document.cookie).split(";");
for (let el of cookies) {
el = el.trimStart();
if(el.indexOf(key) == 0){
return el.substr(key.length, el.length);
}
}
return "";
}
/** /**
* Function that load the file with translation from the specified lang and return a dictionnary * Function that load the file with translation from the specified lang and return a dictionnary
* @param select the language to load. could be null to fetch the cookies for an answer * @param select the language to load. could be null to fetch the cookies for an answer

View File

@ -1,4 +1,5 @@
import './assets/main.css' import './assets/main.css'
import 'vue3-toastify/dist/index.css';
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './Login.vue' import App from './Login.vue'

View File

@ -0,0 +1,28 @@
import { restGet, restPost } from './restConsumer.js'
export async function login(user, pass, exp){
return restPost("/login", {login: user, password: pass, expiration: exp});
}
export async function register(user, pass, mail){
return restPost("/user", {name: user, password: pass, mail: mail});
restPost("/login", {login: user, password: pass, expiration: exp})
}
/**
* get informations on a specific user.
* Leaving the id empty will return the user's value based on his token
* if the user is not authenticated. then an empty array should be returned
*/
export async function getUser(id){
const endpoint = "/user" + id != null ? "/" + id : "";
return restGet(endpoint);
}
/**
* Reserved for secretary roles. Allow to list all user on the plateform
*/
export async function getAllUsers(){
return restGet("/users");
}

View File

@ -0,0 +1,45 @@
import { getCookie } from '../utils.js'
import { toast } from 'vue3-toastify'
const restURL = import.meta.env.PROD ? "https://clyde.herisson.ovh/api" : "http://localhost:8080"
export async function restGet(endPoint) {
return await _rest(endPoint, {method: "GET"});
}
export async function restPost(endPoint, data) {
return await _rest(endPoint, {method: "POST", body: data});
}
export async function restDelete(endPoint, data) {
return await _rest(endPoint, {method: "DELETE", body: data});
}
export async function restPatch(endPoint, data) {
return await _rest(endPoint, {method: "PATCH", body: data});
}
/**
* backbone for the request made by the frontend
*
* specification
* - If the user has "session_token" cookie set, it will use it in the authorization field of the http request
* - The result will be returned as a json to access fields easily ( the backend should send json response )
*
* @Example _rest("/ping", {user: data}) -> {id:0, txt:"pong"}
*/
async function _rest(endPoint, config){
endPoint.at(0) != "/" ? console.error("Carefull, you certainly should put a / at the begenning of your endPoint ") : true;
let session_token = getCookie("session_token");
let headers = new Headers({'Authorization': session_token});
config['headers'] = headers;
return toast.promise(fetch(restURL + endPoint, config),
{
pending: config['pending'] != null ? config['pending'] : 'pending',
error: config['error'] != null ? config['error'] : 'Network Failure...',
success: config['success'] != null ? config['success'] : {render(res){
return res.ok ? "Success" : "error";
}},
})
.then( e => e.json()).catch( e => e );
}

17
frontend/src/utils.js Normal file
View File

@ -0,0 +1,17 @@
/**
* Return the content of a cookie with specified key
* @param key cookie name
*/
function getCookie(key){
key = key + "="
let cookies = decodeURIComponent(document.cookie).split(";");
for (let el of cookies) {
el = el.trimStart();
if(el.indexOf(key) == 0){
return el.substr(key.length, el.length);
}
}
return "";
}
export {getCookie};