Get Recaptcha working again. Add a backchannel for stage prodding.
Recaptcha is a special snowflake because it dynamically loads the script and THEN renders with info from the registration request. This means we need a back-channel for the UI component to 'tell' the stage that everything is loaded. This Just Works which is nice.
This commit is contained in:
parent
991a96cfc5
commit
3e903be73d
2 changed files with 48 additions and 8 deletions
|
@ -38,8 +38,9 @@ class Register extends Signup {
|
||||||
this.username = null; // desired
|
this.username = null; // desired
|
||||||
this.email = null; // desired
|
this.email = null; // desired
|
||||||
this.password = null; // desired
|
this.password = null; // desired
|
||||||
this.params = {}; // random other stuff (e.g. query params)
|
this.params = {}; // random other stuff (e.g. query params, NOT params from the server)
|
||||||
this.credentials = null;
|
this.credentials = null;
|
||||||
|
this.activeStage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setClientSecret(secret) {
|
setClientSecret(secret) {
|
||||||
|
@ -66,6 +67,10 @@ class Register extends Signup {
|
||||||
return this.credentials;
|
return this.credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getServerData() {
|
||||||
|
return this.data || {};
|
||||||
|
}
|
||||||
|
|
||||||
setStep(step) {
|
setStep(step) {
|
||||||
this._step = 'Register.' + step;
|
this._step = 'Register.' + step;
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -112,6 +117,7 @@ class Register extends Signup {
|
||||||
var flow = self.chooseFlow(error.data.flows);
|
var flow = self.chooseFlow(error.data.flows);
|
||||||
|
|
||||||
if (flow) {
|
if (flow) {
|
||||||
|
console.log("Active flow => %s", JSON.stringify(flow));
|
||||||
var flowStage = self.firstUncompletedStageIndex(flow);
|
var flowStage = self.firstUncompletedStageIndex(flow);
|
||||||
return self.startStage(flow.stages[flowStage]);
|
return self.startStage(flow.stages[flowStage]);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +180,7 @@ class Register extends Signup {
|
||||||
}
|
}
|
||||||
|
|
||||||
var stage = new StageClass(MatrixClientPeg.get(), this);
|
var stage = new StageClass(MatrixClientPeg.get(), this);
|
||||||
|
this.activeStage = stage;
|
||||||
return stage.complete().then(function(request) {
|
return stage.complete().then(function(request) {
|
||||||
if (request.auth) {
|
if (request.auth) {
|
||||||
return self._tryRegister(request.auth);
|
return self._tryRegister(request.auth);
|
||||||
|
@ -220,6 +227,13 @@ class Register extends Signup {
|
||||||
return otherFlow;
|
return otherFlow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tellStage(stageName, data) {
|
||||||
|
if (this.activeStage && this.activeStage.type === stageName) {
|
||||||
|
console.log("Telling stage %s about something..", stageName);
|
||||||
|
this.activeStage.onReceiveData(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,10 @@ class Stage {
|
||||||
// Has a "message" string and an "isFatal" flag.
|
// Has a "message" string and an "isFatal" flag.
|
||||||
return q.reject("NOT IMPLEMENTED");
|
return q.reject("NOT IMPLEMENTED");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onReceiveData() {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Stage.TYPE = "NOT IMPLEMENTED";
|
Stage.TYPE = "NOT IMPLEMENTED";
|
||||||
|
|
||||||
|
@ -39,12 +43,22 @@ DummyStage.TYPE = "m.login.dummy";
|
||||||
class RecaptchaStage extends Stage {
|
class RecaptchaStage extends Stage {
|
||||||
constructor(matrixClient, signupInstance) {
|
constructor(matrixClient, signupInstance) {
|
||||||
super(RecaptchaStage.TYPE, matrixClient, signupInstance);
|
super(RecaptchaStage.TYPE, matrixClient, signupInstance);
|
||||||
|
this.defer = q.defer();
|
||||||
|
this.publicKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onReceiveData(data) {
|
||||||
|
if (data !== "loaded") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._attemptRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
complete() {
|
complete() {
|
||||||
var publicKey;
|
var publicKey;
|
||||||
if (this.signupInstance.params['m.login.recaptcha']) {
|
var serverParams = this.signupInstance.getServerData().params;
|
||||||
publicKey = this.signupInstance.params['m.login.recaptcha'].public_key;
|
if (serverParams && serverParams["m.login.recaptcha"]) {
|
||||||
|
publicKey = serverParams["m.login.recaptcha"].public_key;
|
||||||
}
|
}
|
||||||
if (!publicKey) {
|
if (!publicKey) {
|
||||||
return q.reject({
|
return q.reject({
|
||||||
|
@ -53,12 +67,26 @@ class RecaptchaStage extends Stage {
|
||||||
isFatal: true
|
isFatal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this._attemptRender();
|
||||||
|
|
||||||
var defer = q.defer();
|
return this.defer.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
_attemptRender() {
|
||||||
|
if (!global.grecaptcha) {
|
||||||
|
console.error("grecaptcha not loaded!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.publicKey) {
|
||||||
|
console.error("No public key for recaptcha!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var self = this;
|
||||||
global.grecaptcha.render('mx_recaptcha', {
|
global.grecaptcha.render('mx_recaptcha', {
|
||||||
sitekey: publicKey,
|
sitekey: this.publicKey,
|
||||||
callback: function(response) {
|
callback: function(response) {
|
||||||
return defer.resolve({
|
return self.defer.resolve({
|
||||||
auth: {
|
auth: {
|
||||||
type: 'm.login.recaptcha',
|
type: 'm.login.recaptcha',
|
||||||
response: response
|
response: response
|
||||||
|
@ -66,8 +94,6 @@ class RecaptchaStage extends Stage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return defer.promise;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecaptchaStage.TYPE = "m.login.recaptcha";
|
RecaptchaStage.TYPE = "m.login.recaptcha";
|
||||||
|
|
Loading…
Reference in a new issue