Skip to content

Commit

Permalink
feature-[167190530]: Implement User Signout (#22)
Browse files Browse the repository at this point in the history
Add a signout route to set token to inactive
Add an integration test
Add feature to swagger documentation

[Delivers #167190530]
  • Loading branch information
ayodejiAA authored and dinobi committed Aug 6, 2019
1 parent d18ecfb commit 63d2273
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 5 deletions.
23 changes: 21 additions & 2 deletions server/controllers/Sessions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const { Session } = models;
/**
*
*
* @class Session
* @class Sessions
*/
class Sessions {
/**
Expand Down Expand Up @@ -45,7 +45,7 @@ class Sessions {
const { devicePlatform, userAgent } = getUserAgent(req);
const { id, dataValues } = user;
const expiresAt = expiryDate(devicePlatform);
const token = generateToken(id);
const token = generateToken({ id });
await Session.create({
userId: id,
token,
Expand All @@ -61,6 +61,25 @@ class Sessions {
serverError(res);
}
}

/**
*
*
* @static
* @param {object} req - request object
* @param {object} res - response object
* @memberof Sessions
* @returns {json} object
*/
static async destroy(req, res) {
try {
const token = req.headers.authorization;
await Session.update({ active: false }, { where: { token } });
return serverResponse(res, 200, { message: 'sign out successful' });
} catch (error) {
serverError(res);
}
}
}

export default Sessions;
40 changes: 40 additions & 0 deletions server/docs/authors-haven-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,40 @@ paths:
application/json:
schema:
"$ref": "#/components/schemas/fbserverResponse"

/api/v1/sessions/destroy:
get:
summary: Sign out Route
description: Sign out Route
responses:
"200":
description: Sign out successful
content:
application/json:
schema:
"$ref": "#/components/schemas/signoutResponse"
"400":
description: Bad request
content:
application/json:
schema:
"$ref": "#/components/schemas/errorResponse"
"403":
description: Incorrect username or password
content:
application/json:
schema:
"$ref": "#/components/schemas/errorResponse"
"500":
description: Server Error
content:
application/json:
schema:
"$ref": "#/components/schemas/serverResponse"
security:
- BearerAuth: []


components:
securitySchemes:
BearerAuth:
Expand Down Expand Up @@ -210,3 +244,9 @@ components:
properties:
message:
type: string
signoutResponse:
type: object
properties:
message:
type: string

2 changes: 1 addition & 1 deletion server/helpers/findToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const findToken = async (param) => {
const session = await Session.findOne({ active: true }, { where: param });
if (new Date(Date.now()) >= session.expiresAt) {
await Session.update({ active: false }, { where: param });
return undefined;
return false;
}

return session;
Expand Down
1 change: 1 addition & 0 deletions server/routes/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ import Sessions from '../controllers/Sessions';
const router = express.Router();

router.post('/create', Sessions.create);
router.get('/destroy', Sessions.destroy);

export default router;
2 changes: 1 addition & 1 deletion test/helpers/findToken.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ describe('verify token middleware', () => {
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
};
const session = await findToken(params);
expect(session).to.equal(undefined);
expect(session).to.equal(false);
});
});
46 changes: 45 additions & 1 deletion test/users/sessions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import models from '../../server/database/models';
chai.use(chaiHttp);

const LOGIN_URL = `${process.env.BASE_URL}/sessions/create`;
const { create } = Sessions;
const { create, destroy } = Sessions;
const { Session } = models;
const { rightUserWithUserName, rightUserWithEmail, wrongUser } = userData;

Expand Down Expand Up @@ -118,3 +118,47 @@ describe('LOGIN SERVER ERROR TEST', () => {
sinon.assert.calledOnce(next);
});
});

describe('Sign out Test', () => {
let sessionToken;
before(async () => {
const response = await chai
.request(app)
.post(`${LOGIN_URL}`)
.send(rightUserWithEmail);
sessionToken = response.body.token;
});

it('should set session active to false when signing out', async () => {
const response = await chai
.request(app)
.get('/api/v1/sessions/destroy')
.set('authorization', sessionToken);
expect(response).to.have.status(200);
expect(response.body.message).to.deep.equal('sign out successful');
});

it('sign out successful even when token is invalid', async () => {
const response = await chai
.request(app)
.get('/api/v1/sessions/destroy')
.set('authorization', 'invalid.session.Token');
expect(response).to.have.status(200);
expect(response.body.message).to.deep.equal('sign out successful');
});

it('should respond with error 500 if there is an error', async () => {
const stubfunc = { destroy };
const sandbox = sinon.createSandbox();
sandbox.stub(stubfunc, 'destroy').rejects(new Error('Server Error'));

const next = sinon.spy();
const res = {
status: () => ({
json: next
})
};
await destroy({}, res);
sinon.assert.calledOnce(next);
});
});

0 comments on commit 63d2273

Please sign in to comment.