Commit d6e932a7 authored by Romain Loth's avatar Romain Loth

used js module pattern (cmxClt) and almost finished all client-side controllers factorization

parent 40322a00
...@@ -151,7 +151,8 @@ def user(): ...@@ -151,7 +151,8 @@ def user():
def login(): def login():
if request.method == 'GET': if request.method == 'GET':
return render_template( return render_template(
"login.html" "login.html",
doors_connect = config['DOORS_HOST']+':'+config['DOORS_PORT']
) )
elif request.method == 'POST': elif request.method == 'POST':
# TODO sanitize # TODO sanitize
...@@ -341,9 +342,8 @@ def sanitize(value): ...@@ -341,9 +342,8 @@ def sanitize(value):
return san_typed_val return san_typed_val
########### MAIN ########### ########### MAIN ###########
# this only uses the dev server (in prod we're run by unicorn and not as main)
if __name__ == "__main__": if __name__ == "__main__":
# our app should be bound to an ip (cf stackoverflow.com/a/30329547/2489184) # our app should be bound to an ip (cf stackoverflow.com/a/30329547/2489184)
app.run(host=config['COMEX_HOST'], port=int(config['COMEX_PORT'])) app.run(host=config['COMEX_HOST'], port=int(config['COMEX_PORT']))
/**
* @fileoverview
* Login via Doors
* @todo
* - package.json
*
* @version 1
* @copyright ISCPIF-CNRS 2016
* @author romain.loth@iscpif.fr
*
* @requires comex_user_shared
* @requires comex_user_shared_auth
*/
// initialize form controllers
cmxClt.uform.initialize("comex_login_form", loginValidate)
// initialize auth with doors
cmxClt.uauth.emailIdSupposedToExist = true
// done when anything in the form changes
function loginValidate() {
// console.log("loginValidate Go")
cmxClt.uauth.earlyValidate()
// TODO checkPassStatusSingle()
if (cmxClt.uauth.passStatus
&& cmxClt.uauth.emailStatus
&& cmxClt.uauth.captchaStatus) {
cmxClt.uform.submitButton.disabled = false
}
else {
cmxClt.uform.submitButton.disabled = true
}
}
function loginDoorsThenTestUidAndSubmit(){
cmxClt.uform.mainMessage.innerHTML = "Logging in ISCPIF Doors..."
// all values from the form have now been validated
var emailValue = cmxClt.uauth.email.value
var passValue = cmxClt.uauth.pass1.value
// KNOCKING ON THE DOORS -------------------------------------
// /!\ async
callDoors(
"user",
[emailValue, passValue],
// callback: get uid to send to server -------------------
function(doorsResp) {
console.log("login resp:", doorsResp)
testUidAndSubmit(doorsResp)
}
)
}
function testUidAndSubmit(doorsResp) {
var doorsUid = doorsResp[0]
var doorsMsg = doorsResp[1]
if (doorsUid == null) {
cmxClt.uform.mainMessage.innerHTML = "Problem with doors login..."
cmxClt.uform.mainMessage.style.color = cmxClt.colorRed
cmxClt.uform.submitButton.disabled = false
}
else {
// fill in the answer we got
// £TODO fix scope uauth and uform ?
uidInput.value = doorsUid
console.info("form was validated and registered@doors: submitting now")
//==== SEND! ====
theForm.submit()
//===============
}
}
console.log("login controllers load OK")
/**
* @fileoverview
* Profile 1/overview and 2/completing via Doors
* @todo
* - package.json
*
* @version 1
* @copyright ISCPIF-CNRS 2016
* @author romain.loth@iscpif.fr
*
* @requires comex_user_shared
* @requires comex_user_shared_auth
*/
// TODO
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* + prepares DB save into COLS * + prepares DB save into COLS
* *
* @todo * @todo
* - harmonize var names (eg 'email' vs 'initialsInput' are both input elts) * - harmonize var names (eg 'cmxClt.uauth.email' vs 'initialsInput' are both input elts)
* - package.json * - package.json
* *
* @version 1 * @version 1
...@@ -17,49 +17,32 @@ ...@@ -17,49 +17,32 @@
* @requires comex_user_shared_auth * @requires comex_user_shared_auth
*/ */
// common vars to user forms // initialize form controllers
// NB other vars defined in main scope but just before their respective funs cmxClt.uform.initialize("comex_reg_form", testAsYouGo) // our form is now in cmxClt.uform.theForm
var theFormId = "comex_login_form"
var theForm = document.getElementById(theFormId)
var wholeFormData
// cf corresponding css classes // initialize auth with doors
var colorWhite = '#fff' cmxClt.uauth.emailIdSupposedToExist = false
var colorRed = '#910'
var colorGreen = '#161'
var colorGrey = '#554'
// vars that will be used during the interaction
var submitButton = document.getElementById('formsubmit')
var mainMessage = document.getElementById('main_validation_message')
var jobLookingDateStatus = false var jobLookingDateStatus = false
submitButton.disabled = true
theForm.onkeyup = testAsYouGo
theForm.onchange = testAsYouGo
theForm.onblur = testAsYouGo
var lastEmailValueCheckedDisplayed = null
// done when anything in the form changes // done when anything in the form changes
function testAsYouGo() { function testAsYouGo() {
// console.log("testAsYouGo Go") // console.log("testAsYouGo Go")
if (email.value != lastEmailValueCheckedDisplayed) { cmxClt.uauth.earlyValidate()
// will update the emailStatus boolean
basicEmailValidate(email.value)
}
captchaStatus = (captcha.value.length == realCaptchaLength)
checkPassStatus()
checkJobDateStatus() checkJobDateStatus()
if (passStatus && emailStatus && captchaStatus && jobLookingDateStatus) { if (cmxClt.uauth.passStatus
submitButton.disabled = false && cmxClt.uauth.emailStatus
&& cmxClt.uauth.captchaStatus
&& jobLookingDateStatus) {
cmxClt.uform.submitButton.disabled = false
} }
else { else {
submitButton.disabled = true cmxClt.uform.submitButton.disabled = true
} }
var now = new Date() var now = new Date()
regTimestamp.value = now.toISOString() regTimestamp.value = now.toISOString()
...@@ -111,7 +94,7 @@ var jobLookingDivStyle = document.getElementById('job_looking_div').style ...@@ -111,7 +94,7 @@ var jobLookingDivStyle = document.getElementById('job_looking_div').style
// case false => Ok("""{"status":"login available"}""") // case false => Ok("""{"status":"login available"}""")
function testDoorsUserExists(emailValue) { function testDoorsUserExists(emailValue) {
// /!\ async // /!\ async
callDoors( cmxClt.uauth.callDoors(
"userExists", "userExists",
[emailValue], [emailValue],
function(doorsResp) { function(doorsResp) {
...@@ -119,6 +102,7 @@ function testDoorsUserExists(emailValue) { ...@@ -119,6 +102,7 @@ function testDoorsUserExists(emailValue) {
var doorsMsg = doorsResp[1] var doorsMsg = doorsResp[1]
// the global status can be true iff login is available and format ok // the global status can be true iff login is available and format ok
// £TODO fix scope (use uauth)
emailStatus = (doorsMsg == "login available") emailStatus = (doorsMsg == "login available")
displayDoorsStatusInRegisterBox(emailStatus, emailValue) displayDoorsStatusInRegisterBox(emailStatus, emailValue)
...@@ -131,8 +115,8 @@ function registerDoorsAndSubmit(){ ...@@ -131,8 +115,8 @@ function registerDoorsAndSubmit(){
mainMessage.innerHTML = "Registering with ISCPIF Doors..." mainMessage.innerHTML = "Registering with ISCPIF Doors..."
// all values from the form have now been validated // all values from the form have now been validated
var emailValue = email.value var emailValue = cmxClt.uauth.email.value
var passValue = pass1.value var passValue = cmxClt.uauth.pass1.value
var wholenameValue = "" var wholenameValue = ""
if (mName.value != "") { if (mName.value != "") {
...@@ -143,7 +127,7 @@ function registerDoorsAndSubmit(){ ...@@ -143,7 +127,7 @@ function registerDoorsAndSubmit(){
} }
// KNOCKING ON THE DOORS ------------------------------------- // REGISTERING ON THE DOORS -------------------------------------
// /!\ async // /!\ async
callDoors( callDoors(
"register", "register",
...@@ -151,6 +135,7 @@ function registerDoorsAndSubmit(){ ...@@ -151,6 +135,7 @@ function registerDoorsAndSubmit(){
// callback: send to DB ------------------- // callback: send to DB -------------------
function(doorsResp) { function(doorsResp) {
console.log("register resp:", doorsResp)
addUidThenSubmit(doorsResp) addUidThenSubmit(doorsResp)
} }
) )
...@@ -161,55 +146,21 @@ function addUidThenSubmit(doorsResp) { ...@@ -161,55 +146,21 @@ function addUidThenSubmit(doorsResp) {
var doorsMsg = doorsResp[1] var doorsMsg = doorsResp[1]
if (doorsUid == null) { if (doorsUid == null) {
mainMessage.innerHTML = "Problem with doors registration... TODO debug" cmxClt.uform.mainMessage.innerHTML = "Problem with doors registration... TODO debug"
mainMessage.style.color = colorRed cmxClt.uform.mainMessage.style.color = cmxClt.colorRed
submitButton.disabled = false cmxClt.uform.submitButton.disabled = false
} }
else { else {
// fill in the answer we got // fill in the answer we got
// £TODO fix scope uauth and uform ?
uidInput.value = doorsUid uidInput.value = doorsUid
console.info("form was validated and registered@doors: submitting now") console.info("form was validated and registered@doors: submitting now")
//==== SEND! ==== //==== SEND! ==================
theForm.submit() cmxClt.uform.theForm.submit()
//=============== //=============================
}
}
var doorsIcon = document.getElementById('doors_ret_icon')
function displayDoorsStatusInRegisterBox (available, emailValue) {
if (available) {
// icon
doorsIconMessage.title = "Ok ID available on Doors"
doorsIcon.style.color = colorGreen
doorsIcon.classList.remove('glyphicon-remove')
doorsIcon.classList.remove('glyphicon-question-sign')
doorsIcon.classList.add('glyphicon-ok')
// message in legend
doorsMessage.innerHTML = "Ok, this email ID is available on Doors!"
doorsMessage.style.color = colorGreen
} }
else {
// icon
doorsIconMessage.title = "Sorry ID already taken on Doors!"
doorsIcon.style.color = colorRed
doorsIcon.classList.remove('glyphicon-ok')
doorsIcon.classList.remove('glyphicon-question-sign')
doorsIcon.classList.add('glyphicon-remove')
// message in legend
doorsMessage.innerHTML = "Sorry this email ID is already taken on Doors!"
doorsMessage.style.color = colorRed
}
// to debounce further actions in testAsYouGo
// return to neutral is also in testAsYouGo
lastEmailValueCheckedDisplayed = emailValue
} }
// validateAndMsg() : bool (validates fields before doors registration and send) // validateAndMsg() : bool (validates fields before doors registration and send)
...@@ -224,20 +175,19 @@ function validateAndMsg() { ...@@ -224,20 +175,19 @@ function validateAndMsg() {
// not necessary b/c button type is set and is != "submit" // not necessary b/c button type is set and is != "submit"
// submitEvent.preventDefault() // submitEvent.preventDefault()
submitButton.disabled = true cmxClt.uform.submitButton.disabled = true
mainMessage.style.display = 'block' cmxClt.uform.mainMessage.style.display = 'block'
var valid = true var valid = true
// TODO pass mainMessage ref as arg cmxClt.uform.mainMessage.innerHTML = "Validating the form..."
mainMessage.innerHTML = "Validating the form..."
// also reformat the jobDate from "YYYY/MM/DD" to ISO // also reformat the jobDate from "YYYY/MM/DD" to ISO
if (jobDate.value.length) jobDate.value = (new Date(jobDate.value)).toISOString() if (jobDate.value.length) jobDate.value = (new Date(jobDate.value)).toISOString()
// objectify the form // objectify the form
wholeFormData = new FormData(theForm); cmxClt.uform.wholeFormData = new FormData(theForm);
var missingFields = [] var missingFields = []
var toolongFields = [] var toolongFields = []
...@@ -255,7 +205,7 @@ function validateAndMsg() { ...@@ -255,7 +205,7 @@ function validateAndMsg() {
// skip doors_uid done afterwards if form ok // skip doors_uid done afterwards if form ok
if (fieldName == 'doors_uid') continue ; if (fieldName == 'doors_uid') continue ;
var actualValue = wholeFormData.get(fieldName) var actualValue = cmxClt.uform.wholeFormData.get(fieldName)
// console.log("actualValue", actualValue) // console.log("actualValue", actualValue)
...@@ -296,11 +246,11 @@ function validateAndMsg() { ...@@ -296,11 +246,11 @@ function validateAndMsg() {
// RESULTS // RESULTS
if (valid) { if (valid) {
// add the captchaCheck inside the form (jquery interference) // add the captchaCheck inside the form (TODO should be automatic via realperson or uauth submodules)
captchaCheck.value = $(captcha).realperson('getHash') cmxClt.uauth.captchaCheck.value = $(captcha).realperson('getHash')
mainMessage.innerHTML = "Form is valid... Will register and submit..." cmxClt.uform.mainMessage.innerHTML = "Form is valid... Will register and submit..."
mainMessage.style.display = 'block' cmxClt.uform.mainMessage.style.display = 'block'
return true return true
} }
...@@ -308,11 +258,11 @@ function validateAndMsg() { ...@@ -308,11 +258,11 @@ function validateAndMsg() {
console.warn("form is not valid") console.warn("form is not valid")
// TODO highlight invalid fields // TODO highlight invalid fields
submitButton.disabled = false cmxClt.uform.submitButton.disabled = false
var errorMessage = '' var errorMessage = ''
if (missingFields.length) { if (missingFields.length) {
errorMessage += "Please fill the missing fields: " + ulListFromLabelsArray(missingFields, ["red"]) errorMessage += "Please fill the missing fields: " + cmxClt.ulListFromLabelsArray(missingFields, ["red"])
} }
// length is handled by each input's maxlength // length is handled by each input's maxlength
...@@ -321,7 +271,7 @@ function validateAndMsg() { ...@@ -321,7 +271,7 @@ function validateAndMsg() {
if (jobDate.value.length) jobDate.value = jobDate.value.slice(0,10).replace(/-/g,"/") if (jobDate.value.length) jobDate.value = jobDate.value.slice(0,10).replace(/-/g,"/")
// display (TODO setTimeout and fade) // display (TODO setTimeout and fade)
mainMessage.innerHTML = errorMessage cmxClt.uform.mainMessage.innerHTML = errorMessage
return false return false
} }
} }
...@@ -359,12 +309,12 @@ function checkShowPic() { ...@@ -359,12 +309,12 @@ function checkShowPic() {
if (theFile.size > max_size) { if (theFile.size > max_size) {
// msg pb // msg pb
picMsg.innerHTML = "The picture is too big (200kB max)!" picMsg.innerHTML = "The picture is too big (200kB max)!"
picMsg.style.color = colorRed picMsg.style.color = cmxClt.colorRed
} }
else { else {
// msg ok // msg ok
picMsg.innerHTML = "Picture ok" picMsg.innerHTML = "Picture ok"
picMsg.style.color = colorGreen picMsg.style.color = cmxClt.colorGreen
// to show the pic when readAsDataURL // to show the pic when readAsDataURL
imgReader.onload = function () { imgReader.onload = function () {
...@@ -389,7 +339,7 @@ function checkShowPic() { ...@@ -389,7 +339,7 @@ function checkShowPic() {
boxShowPicImg.style.display = 'block' boxShowPicImg.style.display = 'block'
// possible re-adjust outerbox ? // possible re-adjust outerbox ?
// showPicImg.style.border = "2px dashed " + colorGrey // showPicImg.style.border = "2px dashed " + cmxClient.colorGrey
} }
...@@ -456,17 +406,22 @@ jobDate.onchange = checkJobDateStatus ...@@ -456,17 +406,22 @@ jobDate.onchange = checkJobDateStatus
function checkJobDateStatus() { function checkJobDateStatus() {
jobLookingDateStatus = (jobBool.value == "No" || validDate.test(jobDate.value)) jobLookingDateStatus = (jobBool.value == "No" || validDate.test(jobDate.value))
if (!jobLookingDateStatus) { if (!jobLookingDateStatus) {
jobDateMsg.style.color = colorRed jobDateMsg.style.color = cmxClt.colorRed
jobDateMsg.innerHTML = 'Date is not yet in the valid format YYYY/MM/DD' jobDateMsg.innerHTML = 'Date is not yet in the valid format YYYY/MM/DD'
} }
else { else {
jobDateMsg.style.color = colorGreen jobDateMsg.style.color = cmxClt.colorGreen
jobDateMsg.innerHTML = 'Ok valid date!' jobDateMsg.innerHTML = 'Ok valid date!'
} }
} }
// £TODO1 move autocomp data to an autocomplete module
// -> local data for countries, jobtitles
// -> ajax fetcher for the scholars, kws and labs
// £TODO2 add a fetcher API on services side
// autocomplete countries // autocomplete countries
$(function() { $(function() {
var $countryInput = $('#country') var $countryInput = $('#country')
...@@ -1077,11 +1032,12 @@ console.log("reg controllers load OK") ...@@ -1077,11 +1032,12 @@ console.log("reg controllers load OK")
// lName.value = "Tartampion" // lName.value = "Tartampion"
// initialsInput.value="JPP" // initialsInput.value="JPP"
// document.getElementById('country').value = "France" // document.getElementById('country').value = "France"
// email.value= makeRandomString(7)+"@om.fr"
// pass1.value="123456+789"
// pass2.value="123456+789"
// document.getElementById('position').value = "atitle" // document.getElementById('position').value = "atitle"
// document.getElementById('keywords').value = "Blabla" // document.getElementById('keywords').value = "Blabla"
// document.getElementById('org').value = "CNRS" // document.getElementById('org').value = "CNRS"
// basicEmailValidate(email.value)
// cmxClt.uauth.email.value= cmxClt.makeRandomString(7)+"@om.fr"
// cmxClt.uauth.pass1.value="123456+789"
// cmxClt.uauth.pass2.value="123456+789"
// cmxClt.uauth.testMailFormatAndExistence(email.value, false)
// --------------------------->8------ // --------------------------->8------
/**
* @fileoverview
* Login via Doors
* @todo
* - package.json
*
* @version 1
* @copyright ISCPIF-CNRS 2016
* @author romain.loth@iscpif.fr
*
* @requires comex_user_shared
* @requires comex_user_shared_auth
*/
// common vars to user forms
// NB other vars defined in main scope but just before their respective funs
var theFormId = "comex_login_form"
var theForm = document.getElementById(theFormId)
var wholeFormData
// cf corresponding css classes
var colorWhite = '#fff'
var colorRed = '#910'
var colorGreen = '#161'
var colorGrey = '#554'
// vars that will be used during the interaction
var submitButton = document.getElementById('formsubmit')
var mainMessage = document.getElementById('main_validation_message')
submitButton.disabled = true
theForm.onkeyup = testAsYouGo
theForm.onchange = testAsYouGo
theForm.onblur = testAsYouGo
var lastEmailValueCheckedDisplayed = null
// done when anything in the form changes
function testAsYouGo() {
// console.log("testAsYouGo Go")
if (email.value != lastEmailValueCheckedDisplayed) {
// will update the emailStatus boolean
basicEmailValidate(email.value)
}
captchaStatus = (captcha.value.length == realCaptchaLength)
checkPassStatusSingle()
if (passStatus && emailStatus && captchaStatus) {
submitButton.disabled = false
}
else {
submitButton.disabled = true
}
}
// NB using new route in doors api/userExists
// case true => Ok("""{"status":"login exists"}""")
// case false => Ok("""{"status":"login available"}""")
function testDoorsUserExists(emailValue) {
// /!\ async
callDoors(
"userExists",
[emailValue],
function(doorsResp) {
var doorsUid = doorsResp[0]
var doorsMsg = doorsResp[1]
// for login the global status can be true iff login exists
emailStatus = (doorsMsg == "login available")
displayDoorsStatusInLoginBox(emailStatus, emailValue)
}
)
}
function doorsThenTestUidAndSubmit(){
mainMessage.innerHTML = "Logging in ISCPIF Doors..."
// all values from the form have now been validated
var emailValue = email.value
var passValue = pass.value
// KNOCKING ON THE DOORS -------------------------------------
// /!\ async
callDoors(
"user",
[emailValue, passValue],
// callback: get uid to send to server -------------------
function(doorsResp) {
testUidAndSubmit(doorsResp)
}
)
}
function testUidAndSubmit(doorsResp) {
var doorsUid = doorsResp[0]
var doorsMsg = doorsResp[1]
if (doorsUid == null) {
mainMessage.innerHTML = "Problem with doors login..."
mainMessage.style.color = colorRed
submitButton.disabled = false
}
else {
// fill in the answer we got
uidInput.value = doorsUid
console.info("form was validated and registered@doors: submitting now")
//==== SEND! ====
theForm.submit()
//===============
}
}
var doorsIcon = document.getElementById('doors_ret_icon')
function displayDoorsStatusInLoginBox (available, emailValue) {
if (available) {
// icon
doorsIconMessage.title = "Sorry this ID isn't recognized on Doors!"
doorsIcon.style.color = colorRed
doorsIcon.classList.remove('glyphicon-ok')
doorsIcon.classList.remove('glyphicon-question-sign')
doorsIcon.classList.add('glyphicon-remove')
// message in legend
doorsMessage.innerHTML = "Sorry this email ID isn't recognized on Doors!"
doorsMessage.style.color = colorRed
}
else {
// icon
doorsIconMessage.title = "Ok ID exists in Doors"
doorsIcon.style.color = colorGreen
doorsIcon.classList.remove('glyphicon-remove')
doorsIcon.classList.remove('glyphicon-question-sign')
doorsIcon.classList.add('glyphicon-ok')
// message in legend
doorsMessage.innerHTML = "Ok, this email ID is recognized in Doors!"
doorsMessage.style.color = colorGreen
}
// to debounce further actions in testAsYouGo
// return to neutral is also in testAsYouGo
lastEmailValueCheckedDisplayed = emailValue
}
console.log("login controllers load OK")
/** /**
* @fileoverview * @fileoverview
* Shared vars and functions for all user forms * Comex Client Module: initialize and expose as *cmxClt* var
* -> shared vars for css
* -> shared vars and functions for all user forms in *cmxClt.uform* submodule
* *
* @todo * @todo
* - package.json * - package.json
...@@ -11,56 +13,73 @@ ...@@ -11,56 +13,73 @@
* *
*/ */
// common vars to user forms
// NB other vars defined in main scope but just before their respective funs // initialize and export cmxClt module
var theFormId = "comex_login_form" var cmxClt = (function() {
var theForm = document.getElementById(theFormId)
var wholeFormData ccModule = {}
// cf corresponding css classes // cf corresponding css classes
var colorWhite = '#fff' ccModule.colorWhite = '#fff'
var colorRed = '#910' ccModule.colorRed = '#910'
var colorGreen = '#161' ccModule.colorGreen = '#161'
var colorGrey = '#554' ccModule.colorGrey = '#554'
// vars that will be used during the interaction
var submitButton = document.getElementById('formsubmit') ccModule.makeRandomString = function (nChars) {
var mainMessage = document.getElementById('main_validation_message') var rando = ""
theForm.onkeyup = testAsYouGo var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
theForm.onchange = testAsYouGo var len = possible.length
theForm.onblur = testAsYouGo for( var i=0; i < nChars; i++ )
rando += possible.charAt(Math.floor(Math.random() * len));
var lastEmailValueCheckedDisplayed = null return rando
}
function makeRandomString(nChars) {
var rando = "" ccModule.ulListFromLabelsArray = function (strArray, ulClassList) {
var possible = "abcdefghijklmnopqrstuvwxyz0123456789"; ulClasses=["minilabels"].concat(ulClassList).join(" ")
var len = possible.length var resultHtml = '<ul class="'+ulClasses+'">'
for( var i=0; i < nChars; i++ ) for (var i in strArray) {
rando += possible.charAt(Math.floor(Math.random() * len)); var label = strArray[i].replace(/_/, " ")
return rando resultHtml += '<li class="minilabel">'+label+'</li>'
} }
resultHtml += '</ul>'
return resultHtml
function ulListFromLabelsArray(strArray, ulClassList) { }
ulClasses=["minilabels"].concat(ulClassList).join(" ")
var resultHtml = '<ul class="'+ulClasses+'">' // basic inputs get normal on focus
for (var i in strArray) { ccModule.makeNormal = function (elt) {
var label = strArray[i].replace(/_/, " ") elt.style.fontWeight = "normal"
resultHtml += '<li class="minilabel">'+label+'</li>' }
// basic inputs get bold on blur
ccModule.makeBold = function (elt){
if (elt.value != "") elt.style.fontWeight = "bold"
}
// common vars to user forms
ccModule.uform = {}
ccModule.uform.theFormId = null
ccModule.uform.theForm = null
ccModule.uform.wholeFormData = null
// vars that will be used during the interaction
ccModule.uform.submitButton = document.getElementById('formsubmit')
ccModule.uform.mainMessage = document.getElementById('main_validation_message')
ccModule.uform.initialize = function(aFormId, aValidationFun) {
ccModule.uform.theFormId = aFormId
ccModule.uform.theForm = document.getElementById(aFormId)
ccModule.uform.theForm.onkeyup = aValidationFun
ccModule.uform.theForm.onchange = aValidationFun
ccModule.uform.theForm.onblur = aValidationFun
} }
resultHtml += '</ul>'
return resultHtml
}
return ccModule
}()) ;
// basic inputs get normal on focus
function makeNormal(elt) {
elt.style.fontWeight = "normal"
}
// basic inputs get bold on blur
function makeBold(elt){
if (elt.value != "") elt.style.fontWeight = "bold"
}
console.log("shared load OK")
/** /**
* @fileoverview * @fileoverview
* Validates email ID and passwords * Validates an email ID and password(s)
* Prepares "captcha" data
* Transmits login credentials to Doors for login or register (fun callDoors) * Transmits login credentials to Doors for login or register (fun callDoors)
* *
* @todo * @todo
...@@ -14,246 +15,346 @@ ...@@ -14,246 +15,346 @@
* @requires realperson (keith-wood.name/realPerson.html) * @requires realperson (keith-wood.name/realPerson.html)
*/ */
// common vars to authenticating user forms
// cmxClt module augmentation
var uidInput = document.getElementById('doors_uid') cmxClt = (function(ccModule) {
var email = document.getElementById('email') // common vars to authenticating/registering in user area
ccModule.uauth = {}
// str of the form: doors_hostname:doors_port var bidule = "trux"
var doorsConnectParam = document.getElementById('doors_connect').value
ccModule.uauth.emailIdSupposedToExist = null
// captchaHash should be appended by itself if normal submit,
// but we may need to do it ourselves (TODO test) ccModule.uauth.uidInput = document.getElementById('doors_uid')
var captcha = document.getElementById('my-captcha') ccModule.uauth.email = document.getElementById('email')
var captchaCheck = document.getElementById('my-captchaHash') ccModule.uauth.emailLbl = document.querySelector('label[for=email]')
// param for generation & validation // str of the form: doors_hostname:doors_port
var realCaptchaLength = 5 ccModule.uauth.doorsConnectParam = document.getElementById('doors_connect').value
// captchaHash should be appended by itself if normal submit,
// but we may need to do it ourselves (TODO test)
var doorsMessage = document.getElementById('doors_ret_message') ccModule.uauth.captcha = document.getElementById('my-captcha')
var doorsIconMessage = document.getElementById('doors_ret_icon_msg') ccModule.uauth.captchaCheck = document.getElementById('my-captchaHash')
var doorsIcon = document.getElementById('doors_ret_icon')
// param for generation & validation
// validate as we go to even get the submitButton ccModule.uauth.realCaptchaLength = 5
var passStatus = false
var emailStatus = false // initialize pseudo captcha
var captchaStatus = false $('#my-captcha').realperson({length: ccModule.uauth.realCaptchaLength});
/* --------------- doors ajax cors function ---------------- // doors-related html elements
* @args: ccModule.uauth.doorsMessage = document.getElementById('doors_ret_message')
* apiAction: 'register' or 'user' or 'userExists' => route to doors api ccModule.uauth.doorsIconMessage = document.getElementById('doors_ret_icon_msg')
* if unknown type, default action is login via doors/api/user ccModule.uauth.doorsIcon = document.getElementById('doors_ret_icon')
*
* data: 3-uple with mail, pass, name // cmxClt.u.auth validators (needed to even get the submitButton)
* ccModule.uauth.passStatus = false
* callback: function that will be called after success AND after error ccModule.uauth.emailStatus = false
* with the return couple ccModule.uauth.captchaStatus = false
* ccModule.uauth.lastEmailValueCheckedDisplayed = null
* returns couple (id, message)
* ---------------------------- ccModule.uauth.earlyValidate = function() {
* ajax success <=> doorsId should be != null except if unknown error // will update the ccModule.uauth.emailStatus boolean
* ajax user infos == doorsMsg ccModule.uauth.testMailFormatAndExistence(ccModule.uauth.email.value, ccModule.uauth.emailIdSupposedToExist)
*
* EXPECTED DOORS ANSWER FORMAT ccModule.uauth.captchaStatus = (ccModule.uauth.captcha.value.length == ccModule.uauth.realCaptchaLength)
* -----------------------------
* { }
* "status": "login ok",
* "userInfo": { // email validation and side-effects
* "id": { // =================================
* "id": "78407900-6f48-44b8-ab37-503901f85458" // NB for login, use --------> expectExists = true
* }, // for registration, use -> expectExists = false
* "password": "68d23eab21abab38542184e8fca2199d",
* "name": "JPP", // no return value, but side effect on icon + msg + emailStatus
* "hashAlgorithm": "PBKDF2", // wrong format ===========================> grey
* "hashParameters": {"iterations": 1000, "keyLength": 128} // format ok, doorsStatus != expectExists => red
* } // format ok, doorsStatus == expectExists => green
* }
*/ ccModule.uauth.testMailFormatAndExistence = function (emailValue, expectExists) {
function callDoors(apiAction, data, callback) {
if (ccModule.uauth.email.value != ccModule.uauth.lastEmailValueCheckedDisplayed) {
// console.warn("=====> CORS <=====")
// console.log("data",data) // tests if email is well-formed
// console.log("apiAction",apiAction) // TODO: better extension and allowed chars set
var emailFormatOk = /^[-A-z0-9_=.+]+@[-A-z0-9_=.+]+\.[-A-z0-9_=.+]{1,4}$/.test(emailValue)
var doorsUid = null
var doorsMsg = null if (! emailFormatOk) {
// restore original lack of message
// all mandatory params for doors ccModule.uauth.doorsMessage.title = 'The email will be checked in our DB after you finish typing'
var mailStr = data[0] ccModule.uauth.doorsIcon.classList.remove('glyphicon-remove')
var passStr = data[1] ccModule.uauth.doorsIcon.classList.remove('glyphicon-ok')
var nameStr = data[2] ccModule.uauth.doorsIcon.classList.add('glyphicon-question-sign')
ccModule.uauth.doorsIcon.style.color = ccModule.colorGrey
// test params and set defaults ccModule.uauth.doorsMessage.innerHTML = ""
if (typeof apiAction == 'undefined'
|| (apiAction != 'register' && apiAction != 'userExists')) { ccModule.uauth.emailLbl.style.color = ""
// currently forces login action unless we got 'register' or userExists
apiAction = 'user' // module-wide flag
console.warn('DBG: forcing user route') ccModule.uauth.emailStatus = false
}
else {
// additional ajax to check login availability
// => updates the emailStatus global boolean
// => displays an icon
// NB using route in doors api/userExists
// case true => Ok("""{"status":"login exists"}""")
// case false => Ok("""{"status":"login available"}""")
// /!\ async
ccModule.uauth.callDoors(
"userExists",
[emailValue],
function(doorsResp) {
var doorsUid = doorsResp[0]
var doorsMsg = doorsResp[1]
// the global status can be true iff login is as expected and format ok
if (expectExists) {
ccModule.uauth.emailStatus = (doorsMsg == "login exists")
}
else {
ccModule.uauth.emailStatus = (doorsMsg == "login available")
}
if (ccModule.uauth.emailStatus) {
// icon
ccModule.uauth.doorsIconMessage.title = "OK: "+doorsMsg+" on Doors"
ccModule.uauth.doorsIcon.style.color = ccModule.colorGreen
ccModule.uauth.doorsIcon.classList.remove('glyphicon-remove')
ccModule.uauth.doorsIcon.classList.remove('glyphicon-question-sign')
ccModule.uauth.doorsIcon.classList.add('glyphicon-ok')
// message in legend
ccModule.uauth.doorsMessage.innerHTML = "OK: "+doorsMsg+" on Doors"
ccModule.uauth.doorsMessage.style.color = ccModule.colorGreen
// label
ccModule.uauth.emailLbl.style.color = ccModule.colorGreen
}
else {
var errMsg = expectExists ? "your ID isn't recognized" : "this ID is already taken"
// icon
ccModule.uauth.doorsIconMessage.title = "Sorry "+errMsg+" on Doors!"
ccModule.uauth.doorsIcon.style.color = ccModule.colorRed
ccModule.uauth.doorsIcon.classList.remove('glyphicon-ok')
ccModule.uauth.doorsIcon.classList.remove('glyphicon-question-sign')
ccModule.uauth.doorsIcon.classList.add('glyphicon-remove')
// message in legend
ccModule.uauth.doorsMessage.innerHTML = "Sorry "+errMsg+" on Doors!"
ccModule.uauth.doorsMessage.style.color = ccModule.colorRed
// label
ccModule.uauth.emailLbl.style.backgroundColor = ccModule.colorRed
}
// to debounce further actions in testAsYouGo
// return to neutral is also in testAsYouGo
ccModule.uauth.lastEmailValueCheckedDisplayed = emailValue
}
)
}
}
} }
if (typeof callback != 'function') { // -----------------------------------------------------------------------
callback = function(retval) { return retval } // pass 1 and pass 2 ~~~> do they match?
// TODO use a most common passwords lists
ccModule.uauth.pass1 = document.getElementById('password')
ccModule.uauth.pass2 = document.getElementById('password2')
ccModule.uauth.passMsg = document.getElementById('password_message')
ccModule.uauth.pass1.onkeyup = ccModule.uauth.checkPassStatus
ccModule.uauth.pass1.onchange = ccModule.uauth.checkPassStatus
if (ccModule.uauth.pass2) {
// could also be attached to form onchange but then called often for nothing
ccModule.uauth.pass2.onkeyup = ccModule.uauth.checkPassStatus
ccModule.uauth.pass2.onchange = ccModule.uauth.checkPassStatus
} }
var ok = ((apiAction == 'userExists' && typeof mailStr != 'undefined' && mailStr)
|| (typeof mailStr != 'undefined'
&& typeof mailStr != 'undefined'
&& typeof nameStr != 'undefined'
&& mailStr && passStr)) // assumes mail and pass will nvr be == 0
if (!ok) { ccModule.uauth.checkPassStatus = function () {
doorsMsg = "Invalid parameters in input data (arg #1)" // £TODO 2 functions:
console.warn('DEBUG callDoors() internal validation failed before ajax') // - check pass #X is valid (with arg pass1 or pass2) [for Login + Register]
// - check 2 passes are identical (only for Register)
if (pass1.value || pass2.value) {
var pass1v = pass1.value
var pass2v = pass2.value
if ((pass1v && pass1v.length > 7)
|| (pass2v && pass2v.length > 7)) {
// test values
if (pass1v == pass2v) {
if (pass1v.match('[^A-z0-9]')) {
passMsg.innerHTML = 'Ok valid passwords!'
passStatus = true
}
else {
passMsg.innerHTML = 'Passwords match but contain only letters and/or digits, please complexify!'
passStatus = false
}
}
else {
passMsg.innerHTML = "The passwords don't match yet."
passStatus = false
}
}
else {
passMsg.innerHTML = "The password is too short (8 chars min)."
passStatus = false
}
}
if (!passStatus) passMsg.style.color = ccModule.colorRed
else passMsg.style.color = ccModule.colorGreen
} }
else {
$.ajax({
contentType: "application/json", /* --------------- doors ajax cors function ----------------
dataType: 'json', * @args:
url: "http://"+doorsConnectParam+"/api/" + apiAction, * apiAction: 'register' or 'user' or 'userExists' => route to doors api
data: JSON.stringify({ * if unknown type, default action is login via doors/api/user
"login": mailStr, *
"password": passStr, * data: 3-uple with mail, pass, name
"name": nameStr *
}), * callback: function that will be called after success AND after error
type: 'POST', * with the return couple
success: function(data) { *
if (typeof data != 'undefined' * returns couple (id, message)
&& apiAction == 'userExists') { * ----------------------------
// userExists success case: it's all in the message :) * ajax success <=> doorsId should be != null except if unknown error
doorsUid = null * ajax user infos == doorsMsg
doorsMsg = data.status *
} * EXPECTED DOORS ANSWER FORMAT
else if (typeof data != 'undefined' * -----------------------------
&& typeof data.userInfo != undefined * {
&& typeof data.userInfo.id != undefined * "status": "login ok",
&& typeof data.userInfo.id.id != undefined * "userInfo": {
&& typeof data.status == 'string') { * "id": {
// main success case: get the id * "id": "78407900-6f48-44b8-ab37-503901f85458"
doorsUid = data.userInfo.id.id * },
doorsMsg = data.status * "password": "68d23eab21abab38542184e8fca2199d",
} * "name": "JPP",
else { * "hashAlgorithm": "PBKDF2",
doorsMsg = "Unknown response for doors apiAction (" + apiAction +"):" * "hashParameters": {"iterations": 1000, "keyLength": 128}
doorsMsg += '"' + JSON.stringify(data).substring(0,10) + '..."' * }
} * }
*/
// start the callback ccModule.uauth.callDoors = function(apiAction, data, callback) {
callback([doorsUid,doorsMsg])
}, // console.warn("=====> CORS <=====")
// console.log("data",data)
error: function(result) { // console.log("apiAction",apiAction)
console.log(result)
if (apiAction == 'user'){ var doorsUid = null
if (result.responseText.match(/"User .+@.+ not found"/)) { var doorsMsg = null
doorsMsg = result.responseText.replace(/^"/g, '').replace(/"$/g, '')
// all mandatory params for doors
var mailStr = data[0]
var passStr = data[1]
var nameStr = data[2]
// test params and set defaults
if (typeof apiAction == 'undefined'
|| (apiAction != 'register' && apiAction != 'userExists')) {
// currently forces login action unless we got 'register' or userExists
apiAction = 'user'
console.warn('DBG: forcing user route')
}
if (typeof callback != 'function') {
callback = function(retval) { return retval }
}
var ok = ((apiAction == 'userExists' && typeof mailStr != 'undefined' && mailStr)
|| (typeof mailStr != 'undefined'
&& typeof mailStr != 'undefined'
&& typeof nameStr != 'undefined'
&& mailStr && passStr)) // assumes mail and pass will nvr be == 0
if (!ok) {
doorsMsg = "Invalid parameters in input data (arg #1)"
console.warn('DEBUG callDoors() internal validation failed before ajax')
}
else {
$.ajax({
contentType: "application/json",
dataType: 'json',
url: "http://"+ccModule.uauth.doorsConnectParam+"/api/" + apiAction,
data: JSON.stringify({
"login": mailStr,
"password": passStr,
"name": nameStr
}),
type: 'POST',
success: function(data) {
if (typeof data != 'undefined'
&& apiAction == 'userExists') {
// userExists success case: it's all in the message :)
doorsUid = null
doorsMsg = data.status
}
else if (typeof data != 'undefined'
&& typeof data.userInfo != undefined
&& typeof data.userInfo.id != undefined
&& typeof data.userInfo.id.id != undefined
&& typeof data.status == 'string') {
// main success case: get the id
doorsUid = data.userInfo.id.id
doorsMsg = data.status
} }
else { else {
// POSS: user message doorsMsg = "Unknown response for doors apiAction (" + apiAction +"):"
console.warn("Unhandled error doors login (" + result.responseText +")") doorsMsg += '"' + JSON.stringify(data).substring(0,10) + '..."'
}
// start the callback
callback([doorsUid,doorsMsg])
},
error: function(result) {
console.log(result)
if (apiAction == 'user'){
if (result.responseText.match(/"User .+@.+ not found"/)) {
doorsMsg = result.responseText.replace(/^"/g, '').replace(/"$/g, '')
}
else {
// POSS: user message
console.warn("Unhandled error doors login (" + result.responseText +")")
}
} }
} else if (apiAction == 'register'){
else if (apiAction == 'register'){ if (typeof result.responseJSON != 'undefined'
if (typeof result.responseJSON != 'undefined' && typeof result.responseJSON.status == 'string') {
&& typeof result.responseJSON.status == 'string') {
doorsMsg = result.responseJSON.status
doorsMsg = result.responseJSON.status // will be useful in the future (actually doors errs don't have a status message yet)
// will be useful in the future (actually doors errs don't have a status message yet) // if doorsMsg == ''
// if doorsMsg == '' }
else {
// POSS: user message
doorsMsg = "Unhandled error doors register (" + result.responseText +")"
console.warn(doorsMsg)
}
} }
else { else {
// POSS: user message doorsMsg = "Unhandled error from unknown doors apiAction (" + apiAction +")"
doorsMsg = "Unhandled error doors register (" + result.responseText +")" console.error(doorsMsg)
console.warn(doorsMsg)
} }
}
else { // start the callback
doorsMsg = "Unhandled error from unknown doors apiAction (" + apiAction +")" callback([doorsUid,doorsMsg])
console.error(doorsMsg) }
} });
}
// start the callback
callback([doorsUid,doorsMsg])
}
});
}
}
// very basic email validation TODO: better extension and allowed chars set :)
// (used in tests "as we go")
function basicEmailValidate (emailValue) {
// tests if email is well-formed
var emailFormatOk = /^[-A-z0-9_=.+]+@[-A-z0-9_=.+]+\.[-A-z0-9_=.+]{1,4}$/.test(emailValue)
if (! emailFormatOk) {
// restore original lack of message
doorsMessage.title = 'The email will be checked in our DB after you type and leave the box.'
doorsIcon.classList.remove('glyphicon-remove')
doorsIcon.classList.remove('glyphicon-ok')
doorsIcon.classList.add('glyphicon-question-sign')
doorsIcon.style.color = colorGrey
emailStatus = false
}
else {
// additional ajax to check login availability
// => updates the emailStatus global boolean
// => displays an icon
testDoorsUserExists(emailValue)
}
}
// pass 1 and pass 2 ~~~> do they match?
// TODO use a most common passwords lists
var pass1 = document.getElementById('password')
var pass2 = document.getElementById('password2')
var passMsg = document.getElementById('password_message')
var passwords = [pass1, pass2]
passwords.forEach ( function(pass) {
// could also be attached to form onchange but then called often for nothing
pass.onkeyup = checkPassStatus
pass.onchange = checkPassStatus
})
function checkPassStatus() {
if (pass1.value || pass2.value) {
var pass1v = pass1.value
var pass2v = pass2.value
if ((pass1v && pass1v.length > 7)
|| (pass2v && pass2v.length > 7)) {
// test values
if (pass1v == pass2v) {
if (pass1v.match('[^A-z0-9]')) {
passMsg.innerHTML = 'Ok valid passwords!'
passStatus = true
}
else {
passMsg.innerHTML = 'Passwords match but contain only letters and/or digits, please complexify!'
passStatus = false
}
}
else {
passMsg.innerHTML = "The passwords don't match yet."
passStatus = false
}
}
else {
passMsg.innerHTML = "The password is too short (8 chars min)."
passStatus = false
} }
}
if (!passStatus) passMsg.style.color = colorRed
else passMsg.style.color = colorGreen
}
// we return our augmented comex client module
return ccModule
})(cmxClt) ;
// pseudo captcha
$('#my-captcha').realperson({length: realCaptchaLength});
$('#my-captcha').val('')
console.log("user shared auth load OK") console.log("user shared auth load OK")
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<!-- NB our js will be at the end --> <!-- NB our js will be at the end -->
<!-- ## Piwik ## --> <!-- ## Piwik ## -->
<script type="text/javascript"> <!-- <script type="text/javascript">
var _paq = _paq || []; var _paq = _paq || [];
_paq.push(['trackPageView']); _paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']); _paq.push(['enableLinkTracking']);
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})(); })();
</script> </script>
<noscript><p><img src="//piwik.iscpif.fr/piwik.php?idsite=4" style="border:0;" alt="" /></p></noscript> <noscript><p><img src="//piwik.iscpif.fr/piwik.php?idsite=4" style="border:0;" alt="" /></p></noscript> -->
<!-- End Piwik Code --> <!-- End Piwik Code -->
......
...@@ -36,10 +36,7 @@ ...@@ -36,10 +36,7 @@
<div class="question"> <div class="question">
<p class="legend">(It is the same login for all the ISC services.)</p> <p class="legend">(It is the same login for all the ISC services.)</p>
<div class="input-group"> <div class="input-group">
<!-- email validation onblur/onchange <!-- email validation onblur/onchange is done by cmxClt.uauth in comex_user_shared_auth.js -->
is done by basicEmailValidate
and testDoorsUserExists
in comex_reg_form_controllers.js -->
<label for="email" class="smlabel input-group-addon">Email</label> <label for="email" class="smlabel input-group-addon">Email</label>
<input id="email" name="email" maxlength="255" <input id="email" name="email" maxlength="255"
type="text" class="form-control" placeholder="email"> type="text" class="form-control" placeholder="email">
...@@ -89,7 +86,7 @@ ...@@ -89,7 +86,7 @@
<label for="my-captcha" class="smlabel input-group-addon">Code</label> <label for="my-captcha" class="smlabel input-group-addon">Code</label>
<input id="my-captcha" name="my-captcha" style="max-width:60%" <input id="my-captcha" name="my-captcha" style="max-width:60%"
type="text" class="form-control input-lg" placeholder="Enter the 5 letters you see beside =>" type="text" class="form-control input-lg" placeholder="Enter the 5 letters you see beside =>"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<!-- == S U B M I T == --> <!-- == S U B M I T == -->
...@@ -106,13 +103,10 @@ ...@@ -106,13 +103,10 @@
<!-- FOR DEBUG: test go-between with Doors --> <!-- FOR DEBUG: test go-between with Doors -->
<p> <p>
<button type=button onclick='callDoors("user", [email.value, pass1.value, initialsInput.value], console.warn)'> <button type=button onclick='cmxClt.uauth.callDoors("user", [cmxClt.uauth.email.value, cmxClt.uauth.pass1.value, null], console.warn)'>
test doors login test doors login
</button> </button>
<button type=button onclick='callDoors("register", [email.value, pass1.value, initialsInput.value], console.warn)'> <button type=button onclick='cmxClt.uauth.callDoors("userExists", [cmxClt.uauth.email.value, null, null], console.warn)'>
test doors register
</button>
<button type=button onclick='callDoors("userExists", [email.value, null, null], console.warn)'>
test doors userExists test doors userExists
</button> </button>
</p> </p>
...@@ -128,5 +122,5 @@ ...@@ -128,5 +122,5 @@
<!-- our js --> <!-- our js -->
<script src="{{ url_for('static', filename='js/comex_user_shared.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_user_shared.js') }}"></script>
<script src="{{ url_for('static', filename='js/comex_user_shared_auth.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_user_shared_auth.js') }}"></script>
<script src="{{ url_for('static', filename='js/comex_user_login_controllers.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_page_login_controllers.js') }}"></script>
{% endblock %} {% endblock %}
...@@ -13,9 +13,22 @@ ...@@ -13,9 +13,22 @@
<div class="spacer col-sm-1 col-md-1">&nbsp;</div> <div class="spacer col-sm-1 col-md-1">&nbsp;</div>
<div class="my_form_box col-sm-8 col-md-8"> <div class="my_form_box col-sm-8 col-md-8">
<!-- INTRODUCTION TEXT -->
<!-- ##################### ( PROFILE OVERVIEW ) #################### -->
<div id="intro"> <div id="intro">
<h2 class="oldstyle">Profile</h2> <h2 class="oldstyle">Your Profile Info</h2>
<p class="mini-hero">
</p>
</div>
<!-- FORM COMPLETING INTRO TEXT -->
<div id="intro">
<h2 class="oldstyle">Complete your profile</h2>
<p class="mini-hero"> <p class="mini-hero">
Take the time to complete your <strong>Community Explorer</strong> profile to generate better maps of your own socio-semantic network . Take the time to complete your <strong>Community Explorer</strong> profile to generate better maps of your own socio-semantic network .
<br/> <br/>
...@@ -27,7 +40,6 @@ ...@@ -27,7 +40,6 @@
</p> </p>
</div> </div>
<!-- ########################### ( FORM ) ########################## --> <!-- ########################### ( FORM ) ########################## -->
<form id="comex_profil_form" enctype="multipart/form-data" <form id="comex_profil_form" enctype="multipart/form-data"
method="post" onsubmit="console.info('submitted')"> method="post" onsubmit="console.info('submitted')">
...@@ -94,10 +106,7 @@ ...@@ -94,10 +106,7 @@
<div class="question"> <div class="question">
<p class="legend">Your email will also be your login for the ISC services.</p> <p class="legend">Your email will also be your login for the ISC services.</p>
<div class="input-group"> <div class="input-group">
<!-- email validation onblur/onchange <!-- email validation onblur/onchange is done by cmxClt.uauth in comex_user_shared_auth.js -->
is done by basicEmailValidate
and testDoorsUserExists
in comex_reg_form_controllers.js -->
<label for="email" class="smlabel input-group-addon">* Email</label> <label for="email" class="smlabel input-group-addon">* Email</label>
<input id="email" name="email" maxlength="255" <input id="email" name="email" maxlength="255"
type="text" class="form-control" placeholder="email"> type="text" class="form-control" placeholder="email">
...@@ -375,5 +384,5 @@ ...@@ -375,5 +384,5 @@
{% block last_imports %} {% block last_imports %}
<!-- our js --> <!-- our js -->
<script src="{{ url_for('static', filename='js/comex_user_shared.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_user_shared.js') }}"></script>
<script src="{{ url_for('static', filename='js/comex_profile_form_controllers.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_page_profile_controllers.js') }}"></script>
{% endblock %} {% endblock %}
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
</label> </label>
<input id="first_name" name="first_name" maxlength="30" <input id="first_name" name="first_name" maxlength="30"
type="text" class="form-control" placeholder="prénom" type="text" class="form-control" placeholder="prénom"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<!-- optionnel --> <!-- optionnel -->
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
</label> </label>
<input id="middle_name" name="middle_name" maxlength="30" <input id="middle_name" name="middle_name" maxlength="30"
type="text" class="form-control" placeholder="autres prénoms" type="text" class="form-control" placeholder="autres prénoms"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<div class="question input-group"> <div class="question input-group">
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
</label> </label>
<input id="last_name" name="last_name" maxlength="30" <input id="last_name" name="last_name" maxlength="30"
type="text" class="form-control" placeholder="nom de famille" type="text" class="form-control" placeholder="nom de famille"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<button class="btn btn-xs btn-default operation" <button class="btn btn-xs btn-default operation"
...@@ -108,10 +108,7 @@ ...@@ -108,10 +108,7 @@
<div class="question"> <div class="question">
<p class="legend">Your email will also be your login for the ISC services.</p> <p class="legend">Your email will also be your login for the ISC services.</p>
<div class="input-group"> <div class="input-group">
<!-- email validation onblur/onchange <!-- email validation onblur/onchange is done by cmxClt.uauth in comex_user_shared_auth.js -->
is done by basicEmailValidate
and testDoorsUserExists
in comex_reg_form_controllers.js -->
<label for="email" class="smlabel input-group-addon">* Email</label> <label for="email" class="smlabel input-group-addon">* Email</label>
<input id="email" name="email" maxlength="255" <input id="email" name="email" maxlength="255"
type="text" class="form-control" placeholder="email"> type="text" class="form-control" placeholder="email">
...@@ -153,14 +150,14 @@ ...@@ -153,14 +150,14 @@
<label for="hon_title" class="smlabel input-group-addon"> Title </label> <label for="hon_title" class="smlabel input-group-addon"> Title </label>
<input id="hon_title" name="hon_title" maxlength="30" <input id="hon_title" name="hon_title" maxlength="30"
type="text" class="form-control autocomp" placeholder="titre" type="text" class="form-control autocomp" placeholder="titre"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<div class="question input-group"> <div class="question input-group">
<label for="position" class="smlabel input-group-addon">* Job Position</label> <label for="position" class="smlabel input-group-addon">* Job Position</label>
<input id="position" name="position" maxlength="30" <input id="position" name="position" maxlength="30"
type="text" class="form-control autocomp" placeholder="titre" type="text" class="form-control autocomp" placeholder="titre"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<div class="question"> <div class="question">
...@@ -298,7 +295,7 @@ ...@@ -298,7 +295,7 @@
<textarea id="interests_text" name="interests_text" maxlength="1200" <textarea id="interests_text" name="interests_text" maxlength="1200"
rows="7" style="resize:none" rows="7" style="resize:none"
class="form-control" placeholder="If you wish, you may describe here your personal interests." class="form-control" placeholder="If you wish, you may describe here your personal interests."
onblur="makeBold(this)" onfocus="makeNormal(this)" onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)"
></textarea> ></textarea>
</div> </div>
<p class="legend">Optional, ~15 lines max (1200 chars)</p> <p class="legend">Optional, ~15 lines max (1200 chars)</p>
...@@ -398,7 +395,7 @@ ...@@ -398,7 +395,7 @@
<label for="my-captcha" class="smlabel input-group-addon">Code</label> <label for="my-captcha" class="smlabel input-group-addon">Code</label>
<input id="my-captcha" name="my-captcha" style="max-width:60%" <input id="my-captcha" name="my-captcha" style="max-width:60%"
type="text" class="form-control input-lg" placeholder="Enter the 5 letters you see beside =>" type="text" class="form-control input-lg" placeholder="Enter the 5 letters you see beside =>"
onblur="makeBold(this)" onfocus="makeNormal(this)"> onblur="cmxClt.makeBold(this)" onfocus="cmxClt.makeNormal(this)">
</div> </div>
<!-- == S U B M I T == --> <!-- == S U B M I T == -->
...@@ -416,13 +413,13 @@ ...@@ -416,13 +413,13 @@
<!-- FOR DEBUG: test go-between with Doors --> <!-- FOR DEBUG: test go-between with Doors -->
<!-- <p> <!-- <p>
<button type=button onclick='callDoors("user", [email.value, pass1.value, initialsInput.value], console.warn)'> <button type=button onclick='cmxClt.uauth.callDoors("user", [cmxClt.uauth.email.value, cmxClt.uauth.pass1.value, initialsInput.value], console.warn)'>
test doors login test doors login
</button> </button>
<button type=button onclick='callDoors("register", [email.value, pass1.value, initialsInput.value], console.warn)'> <button type=button onclick='cmxClt.uauth.callDoors("register", [cmxClt.uauth.email.value, cmxClt.uauth.pass1.value, initialsInput.value], console.warn)'>
test doors register test doors register
</button> </button>
<button type=button onclick='callDoors("userExists", [email.value, null, null], console.warn)'> <button type=button onclick='cmxClt.uauth.callDoors("userExists", [cmxClt.uauth.email.value, null, null], console.warn)'>
test doors userExists test doors userExists
</button> </button>
</p> --> </p> -->
...@@ -439,5 +436,5 @@ ...@@ -439,5 +436,5 @@
<!-- our js --> <!-- our js -->
<script src="{{ url_for('static', filename='js/comex_user_shared.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_user_shared.js') }}"></script>
<script src="{{ url_for('static', filename='js/comex_user_shared_auth.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_user_shared_auth.js') }}"></script>
<script src="{{ url_for('static', filename='js/comex_user_reg_controllers.js') }}"></script> <script src="{{ url_for('static', filename='js/comex_page_reg_controllers.js') }}"></script>
{% endblock %} {% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment