Skip to content

Commit

Permalink
[IAMRISK-3539] Add challenge endpoint for signup (#1467)
Browse files Browse the repository at this point in the history
  • Loading branch information
TSLarson committed Sep 26, 2024
1 parent 231307b commit 35105eb
Show file tree
Hide file tree
Showing 12 changed files with 951 additions and 297 deletions.
570 changes: 426 additions & 144 deletions dist/auth0.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/auth0.min.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/auth0.min.esm.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/auth0.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/auth0.min.js.map

Large diffs are not rendered by default.

506 changes: 370 additions & 136 deletions dist/cordova-auth0-plugin.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/cordova-auth0-plugin.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/cordova-auth0-plugin.min.js.map

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions src/authentication/db-connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,20 @@ DBConnection.prototype.getPasswordResetChallenge = function (cb) {
.end(responseHandler(cb, { ignoreCasing: true }));
};


DBConnection.prototype.getSignupChallenge = function (cb) {
assert.check(cb, { type: 'function', message: 'cb parameter is not valid' });

if (!this.baseOptions.state) {
return cb();
}

var url = urljoin(this.baseOptions.rootUrl, 'dbconnections', 'signup', 'challenge');

return this.request
.post(url)
.send({ state: this.baseOptions.state })
.end(responseHandler(cb, { ignoreCasing: true }));
};

export default DBConnection;
3 changes: 3 additions & 0 deletions src/web-auth/captcha.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var captchaSolved = noop;

var Flow = {
DEFAULT: 'default',
SIGNUP: 'signup',
PASSWORDLESS: 'passwordless',
PASSWORD_RESET: 'password_reset'
};
Expand Down Expand Up @@ -417,6 +418,8 @@ function render(auth0Client, flow, element, options, callback) {
auth0Client.passwordless.getChallenge(challengeCallback);
} else if (flow === Flow.PASSWORD_RESET) {
auth0Client.dbConnection.getPasswordResetChallenge(challengeCallback);
} else if (flow === Flow.SIGNUP) {
auth0Client.dbConnection.getSignupChallenge(challengeCallback);
} else {
auth0Client.getChallenge(challengeCallback);
}
Expand Down
45 changes: 37 additions & 8 deletions src/web-auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -642,15 +642,15 @@ WebAuth.prototype.renewAuth = function (options, cb) {
* Renews an existing session on Auth0's servers using `response_mode=web_message`
*
* Allows you to acquire a new token from Auth0 for a user who already
* has an SSO session established against Auth0 for your domain.
* If the user is not authenticated, the authentication result will be empty
* has an SSO session established against Auth0 for your domain.
* If the user is not authenticated, the authentication result will be empty
* and you'll receive an error like this: `{error: 'login_required'}`.
* The method accepts any valid OAuth2 parameters that would normally be sent to `/authorize`.
*
*
* Everything happens inside an iframe, so it will not reload your application or redirect away from it.
*
* **Important:** If you're not using the hosted login page to do social logins,
* you have to use your own [social connection keys](https://manage.auth0.com/#/connections/social).
*
* **Important:** If you're not using the hosted login page to do social logins,
* you have to use your own [social connection keys](https://manage.auth0.com/#/connections/social).
* If you use Auth0's dev keys, you'll always get `login_required` as an error when calling `checkSession`.
*
* **Important:** Because there is no redirect in this method, `responseType: 'code'` is not supported and will throw an error.
Expand All @@ -664,7 +664,7 @@ WebAuth.prototype.renewAuth = function (options, cb) {
* function(err, authResult) {
* // Authentication tokens or error
* });
*
*
* @method checkSession
* @param {Object} [options]
* @param {String} [options.clientID] the Client ID found on your Application settings page
Expand Down Expand Up @@ -1138,7 +1138,7 @@ WebAuth.prototype.passwordlessVerify = function (options, cb) {

/**
*
* Renders the captcha challenge in the provided element.
* Renders the login captcha challenge in the provided element.
* This function can only be used in the context of a Classic Universal Login Page.
*
* @method renderCaptcha
Expand All @@ -1161,6 +1161,35 @@ WebAuth.prototype.renderCaptcha = function (element, options, callback) {
return captcha.render(this.client, captcha.Flow.DEFAULT, element, options, callback);
};

/**
*
* Renders the signup captcha challenge in the provided element.
* This function can only be used in the context of a Classic Universal Login Page.
*
* @method renderSignupCaptcha
* @param {HTMLElement} element The element where the captcha needs to be rendered
* @param {Object} options The configuration options for the captcha
* @param {Object} [options.templates] An object containing templates for each captcha provider
* @param {Function} [options.templates.auth0] template function receiving the challenge and returning a string
* @param {Function} [options.templates.recaptcha_v2] template function receiving the challenge and returning a string
* @param {Function} [options.templates.recaptcha_enterprise] template function receiving the challenge and returning a string
* @param {Function} [options.templates.hcaptcha] template function receiving the challenge and returning a string
* @param {Function} [options.templates.friendly_captcha] template function receiving the challenge and returning a string
* @param {Function} [options.templates.arkose] template function receiving the challenge and returning a string
* @param {Function} [options.templates.auth0_v2] template function receiving the challenge and returning a string
* @param {Function} [options.templates.error] template function returning a custom error message when the challenge could not be fetched, receives the error as first argument
* @param {String} [options.lang=en] the ISO code of the language for the captcha provider
* @param {captchaLoadedCallback} [callback] An optional callback called after captcha is loaded
* @memberof WebAuth.prototype
*/
WebAuth.prototype.renderSignupCaptcha = function (
element,
options,
callback
) {
return captcha.render(this.client, captcha.Flow.SIGNUP, element, options, callback);
};

/**
*
* Renders the passwordless captcha challenge in the provided element.
Expand Down
90 changes: 90 additions & 0 deletions test/authentication/db-connection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,94 @@ describe('auth0.authentication', function () {
});
});
});

context('dbConnection getSignupChallenge', function () {
context('when the client does not have state', function () {
before(function () {
this.auth0 = new Authentication(this.webAuthSpy, {
domain: 'me.auth0.com',
clientID: '...',
redirectUri: 'http://page.com/callback',
responseType: 'code',
_sendTelemetry: false
});
});

it('should return nothing', function (done) {
this.auth0.dbConnection.getSignupChallenge((err, challenge) => {
expect(err).to.not.be.ok();
expect(challenge).to.not.be.ok();
done();
});
});
});

context('when the client has state', function () {
before(function () {
this.auth0 = new Authentication(this.webAuthSpy, {
domain: 'me.auth0.com',
clientID: '...',
redirectUri: 'http://page.com/callback',
responseType: 'code',
_sendTelemetry: false,
state: '123abc'
});
});

afterEach(function () {
request.post.restore();
});

it('should post state and returns the image/type', function (done) {
sinon.stub(request, 'post').callsFake(function (url) {
expect(url).to.be('https://me.auth0.com/dbconnections/signup/challenge');
return new RequestMock({
body: {
state: '123abc'
},
headers: {
'Content-Type': 'application/json'
},
cb: function (cb) {
cb(null, {
body: {
image: 'svg+yadayada',
type: 'code'
}
});
}
});
});

this.auth0.dbConnection.getSignupChallenge((err, challenge) => {
expect(err).to.not.be.ok();
expect(challenge.image).to.be('svg+yadayada');
expect(challenge.type).to.be('code');
done();
});
});

it('should return the error if network fails', function (done) {
sinon.stub(request, 'post').callsFake(function (url) {
expect(url).to.be('https://me.auth0.com/dbconnections/signup/challenge');
return new RequestMock({
body: {
state: '123abc'
},
headers: {
'Content-Type': 'application/json'
},
cb: function (cb) {
cb(new Error('error error error'));
}
});
});

this.auth0.dbConnection.getSignupChallenge((err, challenge) => {
expect(err.original.message).to.equal('error error error');
done();
});
});
});
});
});

0 comments on commit 35105eb

Please sign in to comment.