Skip to content

Commit 7117bb7

Browse files
committed
✨ Introduce auth header parsing method getTokenFromRequest
1 parent 10c794c commit 7117bb7

File tree

2 files changed

+70
-13
lines changed

2 files changed

+70
-13
lines changed

src/common-libs/auth/index.ts

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,69 @@
1-
const AuthLib = {
2-
async getRolesForAParticipant(participantId: number) {
3-
return participantId; //TODO: add functionality
4-
},
5-
6-
async getParticipantsForATarget(target: {
7-
targetId: number;
8-
target: string;
9-
}) {
10-
return target; //TODO: add functionality
11-
},
1+
import { Request } from '@hapi/hapi';
2+
3+
interface BasicAuth {
4+
username: string | null;
5+
password: string | null;
6+
}
7+
8+
const parseBasic = (credentialsPart: string): BasicAuth => {
9+
let pieces: (string | null)[];
10+
11+
const decoded = Buffer.from(credentialsPart, 'base64').toString('utf8');
12+
13+
if (!decoded) {
14+
throw new Error('Invalid authorization header');
15+
}
16+
17+
const index = decoded.indexOf(':');
18+
19+
if (index === -1) {
20+
pieces = [decoded];
21+
} else {
22+
pieces = [decoded.slice(0, index), decoded.slice(index + 1)];
23+
}
24+
25+
// Allows for usernameless authentication
26+
if (!pieces[0]) {
27+
pieces[0] = null;
28+
}
29+
30+
// Allows for passwordless authentication
31+
if (!pieces[1]) {
32+
pieces[1] = null;
33+
}
34+
35+
return {
36+
username: pieces[0],
37+
password: pieces[1],
38+
};
1239
};
1340

14-
export default AuthLib;
41+
export const getTokenFromRequest = (req: Request): string | null => {
42+
if (!req.headers?.authorization) {
43+
return null;
44+
}
45+
46+
const pieces = req.headers.authorization.split(/\s+/);
47+
48+
if (!pieces || pieces.length !== 2) {
49+
throw new Error('Bad HTTP authentication header format');
50+
}
51+
52+
let credentials: string | null = null;
53+
const schemePart = pieces[0];
54+
const credentialsPart = pieces[1];
55+
56+
switch (schemePart.toLowerCase()) {
57+
case 'basic':
58+
credentials = parseBasic(credentialsPart).password;
59+
break;
60+
case 'bearer':
61+
credentials = credentialsPart;
62+
break;
63+
64+
default:
65+
throw new Error('Unsupported authorization scheme');
66+
}
67+
68+
return credentials;
69+
};

src/server.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Container } from 'typedi';
1313
import { CONFIG } from '../config';
1414
import { createDbConnetion } from './data-providers/postgres';
1515
import v4Models from '@unocha/hpc-api-core/src/db';
16+
import { getTokenFromRequest } from './common-libs/auth';
1617

1718
declare module '@hapi/hapi' {
1819
interface ServerApplicationState {
@@ -46,10 +47,11 @@ async function startServer() {
4647

4748
const apolloServer = new ApolloServer({
4849
schema,
49-
context: () => ({
50+
context: ({ request }: { request: Hapi.Request }) => ({
5051
connection: dbConnection,
5152
models: v4Models(dbConnection),
5253
config: CONFIG,
54+
token: getTokenFromRequest(request),
5355
}),
5456
plugins: [
5557
ApolloServerPluginStopHapiServer({ hapiServer }),

0 commit comments

Comments
 (0)