Skip to content

Commit e98c5bb

Browse files
authored
✨ Feature: Request Account form and direct access (#4833)
1 parent 0a7fbd7 commit e98c5bb

File tree

15 files changed

+383
-215
lines changed

15 files changed

+383
-215
lines changed

services/static-webserver/client/source/boot/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
<!-- <meta property="og:description" id="openGraphDescription" content="open online simulations for Stimulating Peripheral Activity to Relieve Conditions" /> -->
3434
<!-- <meta property="og:image" id="openGraphImage" content="../resource/osparc/favicon-osparc.png" /> -->
3535

36+
<!-- Preload fonts -->
37+
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
38+
<link rel="preload" href="https://fonts.googleapis.com/css?family=Manrope" as="style">
3639
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Manrope">
3740

3841
<style>

services/static-webserver/client/source/class/osparc/Application.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ qx.Class.define("osparc.Application", {
4444
// Call super class
4545
this.base();
4646

47-
this.__preventAutofillBrowserSyles();
47+
this.__preventAutofillBrowserStyles();
4848

4949
// Enable logging in debug variant
5050
if (qx.core.Environment.get("qx.debug")) {
@@ -88,12 +88,12 @@ qx.Class.define("osparc.Application", {
8888
// Setting up auth manager
8989
osparc.auth.Manager.getInstance().addListener("logout", () => this.__restart(), this);
9090

91-
this.__initRouting();
9291
this.__loadCommonCss();
9392

9493
this.__updateTabName();
9594
this.__updateFavicon();
9695

96+
this.__initRouting();
9797
this.__startupChecks();
9898
},
9999

@@ -165,6 +165,12 @@ qx.Class.define("osparc.Application", {
165165
}
166166
break;
167167
}
168+
case "request-account": {
169+
// Route: /#/request-account
170+
osparc.utils.Utils.cookie.deleteCookie("user");
171+
this.__restart();
172+
break;
173+
}
168174
case "reset-password": {
169175
// Route: /#/reset-password/?code={resetCode}
170176
if (urlFragment.params && urlFragment.params.code) {
@@ -193,7 +199,7 @@ qx.Class.define("osparc.Application", {
193199
// Route: /#/error/?message={errorMessage}&status_code={statusCode}
194200
if (urlFragment.params && urlFragment.params.message) {
195201
let msg = urlFragment.params.message;
196-
// Relpace plus sign in URL query string by spaces
202+
// Replace plus sign in URL query string by spaces
197203
msg = msg.replace(/\+/g, "%20");
198204
msg = decodeURIComponent(msg);
199205
osparc.utils.Utils.cookie.deleteCookie("user");
@@ -493,7 +499,7 @@ qx.Class.define("osparc.Application", {
493499
osparc.wrapper.WebSocket.getInstance().disconnect();
494500
},
495501

496-
__preventAutofillBrowserSyles: function() {
502+
__preventAutofillBrowserStyles: function() {
497503
const stylesheet = qx.ui.style.Stylesheet.getInstance();
498504
if (qx.bom.client.Browser.getName() === "chrome" && qx.bom.client.Browser.getVersion() >= 71) {
499505
stylesheet.addRule(

services/static-webserver/client/source/class/osparc/auth/LoginPage.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,15 @@ qx.Class.define("osparc.auth.LoginPage", {
8484

8585
const login = new osparc.auth.ui.LoginView();
8686
const register = new osparc.auth.ui.RegistrationView();
87+
const requestAccount = new osparc.auth.ui.RequestAccount();
8788
const verifyPhoneNumber = new osparc.auth.ui.VerifyPhoneNumberView();
8889
const resetRequest = new osparc.auth.ui.ResetPassRequestView();
8990
const reset = new osparc.auth.ui.ResetPassView();
9091
const login2FAValidationCode = new osparc.auth.ui.Login2FAValidationCodeView();
9192

9293
pages.add(login);
9394
pages.add(register);
95+
pages.add(requestAccount);
9496
pages.add(verifyPhoneNumber);
9597
pages.add(resetRequest);
9698
pages.add(reset);
@@ -106,6 +108,8 @@ qx.Class.define("osparc.auth.LoginPage", {
106108
if (urlFragment.nav && urlFragment.nav.length) {
107109
if (urlFragment.nav[0] === "registration") {
108110
pages.setSelection([register]);
111+
} else if (urlFragment.nav[0] === "request-account") {
112+
pages.setSelection([requestAccount]);
109113
} else if (urlFragment.nav[0] === "reset-password") {
110114
pages.setSelection([reset]);
111115
}
@@ -119,13 +123,18 @@ qx.Class.define("osparc.auth.LoginPage", {
119123
this.fireDataEvent("done", msg);
120124
}, this);
121125

122-
login.addListener("toReset", e => {
123-
pages.setSelection([resetRequest]);
126+
login.addListener("toRegister", () => {
127+
pages.setSelection([register]);
124128
login.resetValues();
125129
}, this);
126130

127-
login.addListener("toRegister", e => {
128-
pages.setSelection([register]);
131+
login.addListener("toRequestAccount", () => {
132+
pages.setSelection([requestAccount]);
133+
login.resetValues();
134+
}, this);
135+
136+
login.addListener("toReset", e => {
137+
pages.setSelection([resetRequest]);
129138
login.resetValues();
130139
}, this);
131140

@@ -167,6 +176,11 @@ qx.Class.define("osparc.auth.LoginPage", {
167176
this.fireDataEvent("done", msg);
168177
});
169178

179+
requestAccount.addListener("done", msg => {
180+
osparc.utils.Utils.cookie.deleteCookie("user");
181+
this.fireDataEvent("done", msg);
182+
});
183+
170184
verifyPhoneNumber.addListener("done", msg => {
171185
login.resetValues();
172186
this.fireDataEvent("done", msg);

services/static-webserver/client/source/class/osparc/auth/core/BaseAuthPage.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,11 @@ qx.Class.define("osparc.auth.core.BaseAuthPage", {
3737
// TODO: remove fix dimensions for the outer container?
3838
this.set({
3939
layout: new qx.ui.layout.VBox(20),
40-
width: 300,
40+
width: this.self().FORM_WIDTH,
4141
height: 300
4242
});
43-
// at least chrome hates it when a password input field exists
44-
// outside a form, so lets accomodate him
45-
this.addListenerOnce("appear", e => {
46-
const el = this.getContentElement();
47-
const form = this._formElement = new qx.html.Element("form", null, {
48-
name: "baseLoginForm",
49-
autocomplete: "on"
50-
});
51-
form.insertBefore(el);
52-
el.insertInto(form);
53-
});
43+
44+
this._form = new qx.ui.form.Form();
5445
this._buildPage();
5546

5647
this.addListener("appear", this._onAppear, this);
@@ -67,6 +58,10 @@ qx.Class.define("osparc.auth.core.BaseAuthPage", {
6758
"done": "qx.event.type.Data"
6859
},
6960

61+
statics: {
62+
FORM_WIDTH: 300
63+
},
64+
7065
/*
7166
*****************************************************************************
7267
MEMBERS
@@ -78,7 +73,7 @@ qx.Class.define("osparc.auth.core.BaseAuthPage", {
7873
* when all is said and done we should remove the form so that the password manager
7974
* knows to save the content of the form. so we save it here.
8075
*/
81-
_formElement: null,
76+
_form: null,
8277
/**
8378
* This method gets called upon construction and
8479
* must be overriden in a subclass
@@ -93,7 +88,7 @@ qx.Class.define("osparc.auth.core.BaseAuthPage", {
9388
*/
9489
resetValues: function() {
9590
this.getChildren().forEach(item => {
96-
// FIXME: should check issubclass of AbstractField
91+
// FIXME: should check is subclass of AbstractField
9792
if (qx.Class.implementsInterface(item, qx.ui.form.IForm) && qx.Class.implementsInterface(item, qx.ui.form.IField)) {
9893
item.resetValue();
9994
}
@@ -105,7 +100,7 @@ qx.Class.define("osparc.auth.core.BaseAuthPage", {
105100
*/
106101
_addTitleHeader: function(txt) {
107102
let lbl = new qx.ui.basic.Label(txt).set({
108-
font: "text-24",
103+
font: "text-20",
109104
alignX: "center"
110105
});
111106
this.add(lbl, {

services/static-webserver/client/source/class/osparc/auth/core/MAuth.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

services/static-webserver/client/source/class/osparc/auth/ui/Login2FAValidationCodeView.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
MIT: https://opensource.org/licenses/MIT
1212
1313
Authors:
14-
* Odei Maiz (odeimaz)
14+
* Odei Maiz (odeimaiz)
1515
1616
************************************************************************ */
1717

@@ -35,7 +35,6 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
3535
},
3636

3737
members: {
38-
__validateCodeTF: null,
3938
__validateCodeBtn: null,
4039
__resendCodeSMSBtn: null,
4140
__resendCodeEmailBtn: null,
@@ -48,11 +47,13 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
4847
});
4948
this.add(introText);
5049

51-
const validateCodeTF = this.__validateCodeTF = new qx.ui.form.TextField().set({
52-
placeholder: this.tr("Type code"),
50+
const formRenderer = new qx.ui.form.renderer.SinglePlaceholder(this._form);
51+
this.add(formRenderer);
52+
53+
const validateCodeTF = new qx.ui.form.TextField().set({
5354
required: true
5455
});
55-
this.add(validateCodeTF);
56+
this._form.add(validateCodeTF, this.tr("Type code"), null, "validationCode");
5657
this.addListener("appear", () => {
5758
validateCodeTF.focus();
5859
validateCodeTF.activate();
@@ -76,10 +77,10 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
7677
});
7778
resendLayout.add(resendCodeDesc);
7879

79-
const resendBtnsLayout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5).set({
80+
const resendButtonsLayout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5).set({
8081
alignY: "middle"
8182
}));
82-
resendLayout.add(resendBtnsLayout);
83+
resendLayout.add(resendButtonsLayout);
8384

8485
const resendCodeSMSBtn = this.__resendCodeSMSBtn = new osparc.ui.form.FetchButton().set({
8586
label: this.tr("Via SMS") + ` (60)`,
@@ -88,7 +89,7 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
8889
this.bind("userPhoneNumber", resendCodeSMSBtn, "visibility", {
8990
converter: pNumber => pNumber ? "visible" : "excluded"
9091
});
91-
resendBtnsLayout.add(resendCodeSMSBtn, {
92+
resendButtonsLayout.add(resendCodeSMSBtn, {
9293
flex: 1
9394
});
9495
resendCodeSMSBtn.addListener("execute", () => {
@@ -110,7 +111,7 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
110111
label: this.tr("Via email") + ` (60)`,
111112
enabled: false
112113
});
113-
resendBtnsLayout.add(resendCodeEmailBtn, {
114+
resendButtonsLayout.add(resendCodeEmailBtn, {
114115
flex: 1
115116
});
116117
resendCodeEmailBtn.addListener("execute", () => {
@@ -140,6 +141,9 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
140141
__validateCodeLogin: function() {
141142
this.__validateCodeBtn.setFetching(true);
142143

144+
const validationCodeTF = this._form.getItems()["validationCode"];
145+
const validationCode = validationCodeTF.getValue();
146+
143147
const loginFun = log => {
144148
this.__validateCodeBtn.setFetching(false);
145149
this.fireDataEvent("done", log.message);
@@ -149,16 +153,17 @@ qx.Class.define("osparc.auth.ui.Login2FAValidationCodeView", {
149153
this.__validateCodeBtn.setFetching(false);
150154
// TODO: can get field info from response here
151155
msg = String(msg) || this.tr("Invalid code");
152-
this.__validateCodeTF.set({
153-
invalidMessage: msg,
154-
valid: false
155-
});
156+
validationCodeTF.setInvalidMessage(msg);
156157

157158
osparc.FlashMessenger.getInstance().logAs(msg, "ERROR");
158159
};
159160

160-
const manager = osparc.auth.Manager.getInstance();
161-
manager.validateCodeLogin(this.getUserEmail(), this.__validateCodeTF.getValue(), loginFun, failFun, this);
161+
if (this._form.validate()) {
162+
const manager = osparc.auth.Manager.getInstance();
163+
manager.validateCodeLogin(this.getUserEmail(), validationCode, loginFun, failFun, this);
164+
} else {
165+
this.__validateCodeBtn.setFetching(true);
166+
}
162167
},
163168

164169
_onAppear: function() {

0 commit comments

Comments
 (0)