Skip to content

Commit

Permalink
Merge pull request #1551 from powerful23/auth-global-signou
Browse files Browse the repository at this point in the history
feat(@aws-amplify/auth): allow globalSignOut
  • Loading branch information
powerful23 authored Sep 6, 2018
2 parents f488d7d + 94d66da commit 9723821
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
8 changes: 8 additions & 0 deletions docs/media/authentication_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ import { Auth } from 'aws-amplify';
Auth.signOut()
.then(data => console.log(data))
.catch(err => console.log(err));

// By doing this, you are revoking all the auth tokens(id token, access token and refresh token)
// which means the user is signed out from all the devices
// Note: although the tokens are revoked, the AWS credentials will remain valid until they expire (which by default is 1 hour)
Auth.signOut({ global: true })
.then(data => console.log(data))
.catch(err => console.log(err));

```

#### Change password
Expand Down
33 changes: 32 additions & 1 deletion packages/auth/__tests__/auth-unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ jest.mock('amazon-cognito-identity-js/lib/CognitoUser', () => {

};

CognitoUser.prototype.globalSignOut = (callback) => {
callback.onSuccess();
};

CognitoUser.prototype.confirmRegistration = (confirmationCode, forceAliasCreation, callback) => {
callback(null, 'Success');
};
Expand Down Expand Up @@ -1349,7 +1353,7 @@ describe('auth unit test', () => {
});
});

describe('signOut', () => {
describe('signOut test', () => {
test('happy case', async () => {
const auth = new Auth(authOptions);

Expand Down Expand Up @@ -1408,6 +1412,33 @@ describe('auth unit test', () => {
spyon2.mockClear();
});

test('happy case for globalSignOut', async () => {
const auth = new Auth(authOptions);
const user = new CognitoUser({
Username: 'username',
Pool: userPool
});

const spyonAuth = jest.spyOn(Credentials, "clear")
.mockImplementationOnce(() => {
return Promise.resolve();
});
const spyon = jest.spyOn(CognitoUserPool.prototype, "getCurrentUser")
.mockImplementationOnce(() => {
return user;
});
const spyon2 = jest.spyOn(CognitoUser.prototype, "globalSignOut");

await auth.signOut({global: true});

expect.assertions(1);
expect(spyon2).toBeCalled();

spyonAuth.mockClear();
spyon.mockClear();
spyon2.mockClear();
});

test('happy case for no userpool', async () => {
// @ts-ignore
const auth = new Auth(authOptionsWithNoUserPoolId);
Expand Down
55 changes: 39 additions & 16 deletions packages/auth/src/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* and limitations under the License.
*/

import { AuthOptions, FederatedResponse, ConfirmSignUpOptions } from './types';
import { AuthOptions, FederatedResponse, ConfirmSignUpOptions, SignOutOpts } from './types';

import {
AWS,
Expand Down Expand Up @@ -1083,11 +1083,35 @@ export default class AuthClass {
return that.currentUserPoolUser()
.then(user => that.verifyUserAttributeSubmit(user, attr, code));
}

private async cognitoIdentitySignOut(opts: SignOutOpts, user) {
return new Promise((res, rej) => {
if (opts && opts.global) {
logger.debug('user global sign out', user);
user.globalSignOut({
onSuccess: (data) => {
logger.debug('global sign out success');
return res();
},
onFailure: (err) => {
logger.debug('global sign out failed', err);
return rej(err);
}
});
} else {
logger.debug('user sign out', user);
user.signOut();
return res();
}
});
}

/**
* Sign out method
* @
* @return - A promise resolved if success
*/
public async signOut(): Promise<any> {
public async signOut(opts?: SignOutOpts): Promise<any> {
try {
await this.cleanCachedItems();
} catch (e) {
Expand All @@ -1097,28 +1121,27 @@ export default class AuthClass {
if (this.userPool) {
const user = this.userPool.getCurrentUser();
if (user) {
logger.debug('user sign out', user);
user.signOut();
await this.cognitoIdentitySignOut(opts, user);
if (this._cognitoAuthClient) {
this._cognitoAuthClient.signOut();
}
} else {
logger.debug('no current Cognito user');
}
} else {
logger.debug('no Congito User pool');
}

const that = this;
return new Promise(async (resolve, reject) => {
try {
await Credentials.set(null, 'guest');
} catch (e) {
logger.debug('cannot load guest credentials for unauthenticated user', e);
} finally {
dispatchAuthEvent('signOut', that.user);
that.user = null;
resolve();
}
});

try {
await Credentials.set(null, 'guest');
} catch (e) {
logger.debug('cannot load guest credentials for unauthenticated user', e);
} finally {
dispatchAuthEvent('signOut', this.user);
this.user = null;
return;
}
}

private async cleanCachedItems() {
Expand Down
4 changes: 4 additions & 0 deletions packages/auth/src/types/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,7 @@ export interface OAuth {
export interface ConfirmSignUpOptions {
forceAliasCreation?: boolean
}

export interface SignOutOpts {
global?: boolean
}

0 comments on commit 9723821

Please sign in to comment.