| {{ st.tr["Problems"] }}
#rightMenu
.clickable(onClick="doClick('modalUser')")
- | {{ !st.user.id ? "Login" : "Update" }}
+ | {{ st.user.id > 0 ? "Update" : "Login" }}
.clickable(onClick="doClick('modalSettings')")
| {{ st.tr["Settings"] }}
.clickable#flagContainer(onClick="doClick('modalLang')")
label(for="username") Name
input#username(type="text" v-model="user.name")
fieldset
- <label for="useremail">Email</label>
- <input id="useremail" type="email" v-model="user.email"/>
+ label(for="useremail") Email
+ input#useremail(type="email" v-model="user.email")
fieldset
- <label for="notifyNew">Notify new moves & games</label>
- <input id="notifyNew" type="checkbox" v-model="user.notify"/>
+ label(for="notifyNew") Notify new moves & games
+ input#notifyNew(type="checkbox" v-model="user.notify")
div(v-show="stage=='Login'")
fieldset
- <label for="nameOrEmail">Name or Email</label>
- <input id="nameOrEmail" type="text" v-model="nameOrEmail"/>
+ label(for="nameOrEmail") Name or Email
+ input#nameOrEmail(type="text" v-model="nameOrEmail")
.button-group
- button#submit(@click="onSubmit()")
+ button#submit(type="button" @click="onSubmit()")
span {{ submitMessage }}
i.material-icons send
button(v-if="stage!='Update'" @click="toggleStage()")
span {{ stage=="Login" ? "Register" : "Login" }}
- button(v-if="stage=='Update'" onClick="location.replace('/logout')")
+ button(v-else onClick="location.replace('/logout')")
span Logout
#dialog(:style="{display: displayInfo}") {{ infoMsg }}
</template>
name: 'my-upsert-user',
data: function() {
return {
- user: store.state.user, //initialized with global user object
+ user: store.state.user,
nameOrEmail: "", //for login
- stage: (!store.state.user.id ? "Login" : "Update"),
+ stage: (store.state.user.id > 0 ? "Update" : "Login"), //TODO?
infoMsg: "",
enterTime: Number.MAX_SAFE_INTEGER, //for a basic anti-bot strategy
};
ajax(this.ajaxUrl(), this.ajaxMethod(),
this.stage == "Login" ? { nameOrEmail: this.nameOrEmail } : this.user,
res => {
-
- console.log("receive login infos");
- console.log(res);
-
this.infoMsg = this.infoMessage();
if (this.stage != "Update")
{
this.nameOrEmail = "";
this.user["email"] = "";
- this.user["name"] = "";
-
- debugger; //TODO: 2 passages ici au lieu d'1 lors du register
-
+ // Update global object
+ this.user["name"] = res.name;
+ this.user["id"] = res.id;
// Store our identifiers in local storage (by little anticipation...)
localStorage["myid"] = res.id;
localStorage["myname"] = res.name;
- // Also in global object
- this.st.user.id = res.id;
- this.st.user.name = res.name;
}
setTimeout(() => {
this.infoMsg = "";
return () => import(/* webpackChunkName: "view-[request]" */ `@/views/${view}.vue`)
}
+import { ajax } from "@/utils/ajax";
+import { store } from "@/store";
+
export default new Router({
routes: [
{
name: "rules",
component: loadView("Rules"),
},
+ {
+ path: "/authenticate/:token",
+ name: "authenticate",
+ beforeEnter: (to, from, next) => {
+ ajax(
+ "/authenticate",
+ "GET",
+ {token: to.params["token"]},
+ (res) => {
+ store.state.user.id = res.id;
+ store.state.user.name = res.name;
+ }
+ );
+ next();
+ },
+ redirect: "/",
+ },
+ {
+ path: "/logout",
+ name: "logout",
+ beforeEnter: (to, from, next) => {
+ ajax(
+ "/logout",
+ "GET",
+ () => {
+ store.state.user.id = 0;
+ store.state.user.name = ""; //TODO: localStorage myId myname mysid ?
+ }
+ );
+ next();
+ },
+ redirect: "/",
+ },
// {
// path: "/about",
// name: "about",
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200)
{
+ let res_json = "";
try {
- let res_json = JSON.parse(xhr.responseText);
- if (!res_json.errmsg)
- success(res_json);
- else
- error(res_json.errmsg);
- } catch (e) {
+ res_json = JSON.parse(xhr.responseText);
+ } catch (e) {
// Plain text (e.g. for rules retrieval)
- success(xhr.responseText);
- }
+ return success(xhr.responseText);
+ }
+ if (!res_json.errmsg)
+ success(res_json);
+ else
+ error(res_json.errmsg);
}
};
}
xhr.open(method, params.serverUrl + url, true);
xhr.setRequestHeader('X-Requested-With', "XMLHttpRequest");
- if (["POST","PUT"].includes(method))
+ // Next line because logout and authenticate set (cross-domain in dev mode) cookies
+ if (url.startsWith("/authenticate") || url.startsWith("/logout"))
+ xhr.withCredentials = true;
+ if (["POST","PUT"].includes(method))
{
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify(data));
{
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", params.cors.allowedOrigin);
- res.header("Access-Control-Allow-Headers",
+ res.header("Access-Control-Allow-Credentials", true); //for cookies
+ res.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
// CORS: cross-origin resource sharing options
cors: {
enable: true,
- allowedOrigin: "*",
+ allowedOrigin: "http://localhost:8080",
},
// Lifespan of a (login) cookie
const body =
"Hello " + to.name + "!\n" +
"Access your account here: " +
- params.siteURL + "/authenticate?token=" + token + "\\n" +
+ params.siteURL + "/#/authenticate/" + token + "\\n" +
"Token will expire in " + params.token.expire/(1000*60) + " minutes."
sendEmail(params.mail.noreply, to.email, subject, body, err => {
-
- console.log("send login infos ::");
- console.log(to);
-
// "id" is generally the only info missing on client side,
// but the name is also unknown if log-in with the email.
res.json(err || {id: to.id, name: to.name});
});
});
-router.get('/authenticate', access.unlogged, (req,res) => {
- UserModel.getOne("loginToken", req.query.token, (err,user) => {
+router.get('/authenticate', access.unlogged, access.ajax, (req,res) => {
+ UserModel.getOne("loginToken", req.query.token, (err,user) => {
access.checkRequest(res, err, user, "Invalid token", () => {
// If token older than params.tokenExpire, do nothing
if (Date.now() > user.loginTime + params.token.expire)
secure: !!params.siteURL.match(/^https/),
maxAge: params.cookieExpire,
});
- res.redirect("/");
+ res.json({name:user.name, id:user.id});
});
});
});
});
});
-// Logout on server because the token cookie is httpOnly
-router.get('/logout', access.logged, (req,res) => {
+router.get('/logout', access.logged, access.ajax, (req,res) => {
res.clearCookie("token");
- res.redirect('/');
+ res.json({});
});
module.exports = router;