Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resumeAuth method and autoParseHash flag #790

Merged
merged 4 commits into from
Jan 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@ lock.show();
lock.show({allowedConnections: ["twitter", "facebook"]})
```

### resumeAuth(hash, callback)

If you set the [auth.autoParseHash](#authentication-options) option to `false`, you'll need to call this method to complete the authentication flow. This method is useful when you're using a client-side router that uses a `#` to handle urls (angular2 with `useHash` or react-router with `hashHistory`).
- **hash {String}**: The hash fragment received from the redirect.
- **callback {Function}**: Will be invoked after the parse is done. Has an error (if any) as the first argument and the authentication result as the second one. If there is no hash available, both arguments will be `null`.

#### Example

```js
lock.resumeAuth(hash, function(error, authResult) {
if (error) {
alert("Could not parse hash");
}
console.log(authResult.accessToken);
});
```

### Customization

The appearance of the widget and the mechanics of authentication can be customized with an `options` object which has one or more of the following properties. Each method that opens the dialog can take an `options` object as its first argument.
Expand Down Expand Up @@ -193,6 +210,7 @@ Authentication options are grouped in the `auth` property of the `options` objec
var options = {
auth: {
params: {param1: "value1"},
autoParseHash: true,
redirect: true,
redirectUrl: "some url",
responseMode: "form_post",
Expand All @@ -206,6 +224,7 @@ var options = {
```

- **params {Object}**: Specifies extra parameters that will be sent when starting a login. Defaults to `{}`.
- **autoParseHash {Boolean}**: When set to `true`, Lock will parse the `window.location.hash` string when instantiated. If set to `false`, you'll have to manually resume authentication using the [resumeAuth](#resumeauthhash-callback) method.
- **redirect {Boolean}**: When set to `true`, the default, _redirect mode_ will be used. Otherwise, _popup mode_ is chosen. See [below](#popup-mode) for more details.
- **redirectUrl {String}**: The url Auth0 will redirect back after authentication. Defaults to the empty string `""` (no redirect URL).
- **responseMode {String}**: Should be set to `"form_post"` if you want the code or the token to be transmitted via an HTTP POST request to the `redirectUrl` instead of being included in its query or fragment parts. Otherwise, it should be ommited.
Expand Down
8 changes: 6 additions & 2 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { remove, render } from './ui/box';
import webAPI from './core/web_api';
import {
closeLock,
resumeAuth,
handleAuthCallback,
openLock,
removeLock,
Expand Down Expand Up @@ -52,14 +53,13 @@ export default class Base extends EventEmitter {
go(this.id);

let m = setupLock(this.id, clientID, domain, options, hookRunner, emitEventFn);

this.on('newListener', (type) => {
if (this.validEvents.indexOf(type) === -1) {
l.emitUnrecoverableErrorEvent(m, `Invalid event "${type}".`)
}
});

if (!Base.hasScheduledAuthCallback) {
if (l.auth.autoParseHash(m) && !Base.hasScheduledAuthCallback) {
Base.hasScheduledAuthCallback = true;
setTimeout(handleAuthCallback, 0);
}
Expand Down Expand Up @@ -136,6 +136,10 @@ export default class Base extends EventEmitter {
});
}

resumeAuth(hash, callback) {
resumeAuth(hash, callback);
}

show(opts = {}) {
openLock(this.id, opts);
}
Expand Down
32 changes: 16 additions & 16 deletions src/core/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,36 +27,36 @@ export function setupLock(id, clientID, domain, options, hookRunner, emitEventFn
}

export function handleAuthCallback() {
const hash = global.location.hash;

const ms = read(getCollection, "lock");
const keepHash = ms.filter(m => !l.hashCleanup(m)).size > 0;
const callback = (error, authResult) => {
const parsed = !!(error || authResult);
if (parsed && !keepHash) {
global.location.hash = "";
}
};
resumeAuth(global.location.hash, callback);
}

ms.forEach(m => {
l.auth.redirect(m) && parseHash(m, hash, (result) => {
if (result && !keepHash) {
global.location.hash = "";
}
})
});
export function resumeAuth(hash, callback) {
const ms = read(getCollection, "lock");
ms.forEach(m => l.auth.redirect(m) && parseHash(m, hash, callback));
}

function parseHash(m, hash, cb) {
webApi.parseHash(l.id(m), hash, function(error, parsedHash) {

webApi.parseHash(l.id(m), hash, function(error, authResult) {
if (error) {
l.emitHashParsedEvent(m, error);
} else {
l.emitHashParsedEvent(m, parsedHash);
l.emitHashParsedEvent(m, authResult);
}

if (error) {
l.emitAuthorizationErrorEvent(m, error);
} else if (parsedHash) {
l.emitAuthenticatedEvent(m, parsedHash);
} else if (authResult) {
l.emitAuthenticatedEvent(m, authResult);
}

cb(!!(error || parsedHash))
cb(error, authResult);
});
}

Expand Down
4 changes: 4 additions & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ const { get: getAuthAttribute } = dataFns(["core", "auth"]);
export const auth = {
connectionScopes: m => getAuthAttribute(m, "connectionScopes"),
params: m => tget(m, "authParams") || getAuthAttribute(m, "params"),
autoParseHash: lock => getAuthAttribute(lock, "autoParseHash"),
redirect: lock => getAuthAttribute(lock, "redirect"),
redirectUrl: lock => getAuthAttribute(lock, "redirectUrl"),
responseType: lock => getAuthAttribute(lock, "responseType"),
Expand All @@ -209,6 +210,7 @@ function extractAuthOptions(options) {
audience,
connectionScopes,
params,
autoParseHash,
redirect,
redirectUrl,
responseMode,
Expand All @@ -227,6 +229,7 @@ function extractAuthOptions(options) {
params = typeof params === "object" ? params : {};
// by default is null because we need to know if it was set when we curate the responseType
redirectUrl = typeof redirectUrl === "string" && redirectUrl ? redirectUrl : null;
autoParseHash = typeof autoParseHash === "boolean" ? autoParseHash : true;
redirect = typeof redirect === "boolean" ? redirect : true;
responseMode = typeof responseMode === "string" ? responseMode : undefined;
state = typeof state === "string" ? state : undefined;
Expand Down Expand Up @@ -255,6 +258,7 @@ function extractAuthOptions(options) {
audience,
connectionScopes,
params,
autoParseHash,
redirect,
redirectUrl,
responseMode,
Expand Down