Skip to content

Commit

Permalink
Generate and return an API key when a test user is generated #2670
Browse files Browse the repository at this point in the history
  • Loading branch information
iamleeg committed May 5, 2022
1 parent 340128e commit b7fa16a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 21 deletions.
25 changes: 16 additions & 9 deletions verification/curator-service/api/src/controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ async function findUserByAPIKey(apiKey?: string): Promise<Express.User> {
return user as Express.User;
}

async function getRandomString(bytes: number): Promise<string> {
const randomValues = await crypto.randomBytes(bytes);
return randomValues.toString('hex');
}

/**
* authenticateByAPIKey is a middleware that checks whether the user has a valid API key in their request.
* If they do, then attach the user object to the request and continue; if not then
Expand Down Expand Up @@ -285,11 +290,6 @@ export class AuthController {
},
);

async function getRandomString(bytes: number): Promise<string> {
const randomValues = await crypto.randomBytes(bytes);
return randomValues.toString('hex');
}

/**
* Create a new api key for the logged-in user.
* @note This API cannot be authenticated by API key. If you believe your API key
Expand All @@ -305,18 +305,18 @@ export class AuthController {
// internal server error as you were authenticated but unknown
res.status(500).end();
} else {
const userQuery = { _id: new ObjectId(theUser.id) };
const userID = new ObjectId(theUser.id);
const userQuery = { _id: userID };
const currentUser = await users().findOne(userQuery);
if (!currentUser) {
// internal server error as you were authenticated but unknown
res.status(500).end();
return;
}
// prefix the API key with the user ID to make it easier to find users by API key in auth
const randomPart = await getRandomString(32);
const apiKey = `${theUser.id.toString()}${randomPart}`;
const apiKey = await this.generateAPIKey(userID);
await users().updateOne(
{ _id: new ObjectId(theUser.id) },
{ _id: userID },
{ $set: { apiKey } },
);
res.status(201).json(apiKey).end();
Expand Down Expand Up @@ -590,6 +590,12 @@ export class AuthController {
);
}

private async generateAPIKey(userID: ObjectId) {
const randomPart = await getRandomString(32);
const apiKey = `${userID.toString()}${randomPart}`;
return apiKey;
}

/**
* configureLocalAuth will get or create the user present in the request.
*/
Expand All @@ -606,6 +612,7 @@ export class AuthController {
name: req.body.name,
email: req.body.email,
roles: req.body.roles,
apiKey: await this.generateAPIKey(userId),
...(removeGoogleID !== true && { googleID: '42' }),
} as IUser);
const user = (await users().findOne({
Expand Down
12 changes: 0 additions & 12 deletions verification/curator-service/api/test/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,18 +273,6 @@ describe('api keys', () => {
await request.get('/auth/profile/apiKey').expect(200);
});

it('does not find an API key where none has been set', async () => {
const request = supertest.agent(app);
await request
.post('/auth/register')
.send({
name: 'test-curator',
email: 'foo@bar.com',
})
.expect(200, /test-curator/);
await request.get('/auth/profile/apiKey').expect(404);
});

it('lets the user get their profile by API key', async () => {
const request = supertest.agent(app);
await request
Expand Down

0 comments on commit b7fa16a

Please sign in to comment.