Skip to content

Commit edbd326

Browse files
Merge pull request #2 from docusign/main
add client credential support
2 parents 6249016 + bd8d43d commit edbd326

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

src/models/auth.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,12 @@ export type GenerateAuthTokenBody =
1111
code?: string;
1212
grant_type: 'authorization_code';
1313
}
14-
| { refresh_token?: string; grant_type: 'refresh_token' };
14+
| {
15+
refresh_token?: string;
16+
grant_type: 'refresh_token';
17+
}
18+
| {
19+
client_id?: string;
20+
client_secret?: string;
21+
grant_type: 'client_credentials';
22+
};

src/services/auth.service.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const generateAuthToken = (req: IReq<GenerateAuthTokenBody>, res: IRes) =
2020
const accessToken = jwt.sign({ type: 'access_token', sub: crypto.randomUUID(), email: `${crypto.randomUUID()}@test.com` }, env.JWT_SECRET_KEY, {
2121
expiresIn: 3600,
2222
});
23+
2324
const refreshToken = jwt.sign({ type: 'refresh_token' }, env.JWT_SECRET_KEY);
2425

2526
const jwtResponse = {
@@ -29,16 +30,38 @@ export const generateAuthToken = (req: IReq<GenerateAuthTokenBody>, res: IRes) =
2930
refresh_token: refreshToken,
3031
};
3132

32-
const decodedAuthCode = decodeURIComponent(env.AUTHORIZATION_CODE.replace(/\+/g, '%20'));
33-
34-
if (req.body.grant_type === 'authorization_code' && (req.body.code === decodedAuthCode || req.body.code === env.AUTHORIZATION_CODE)) {
33+
if (
34+
req.body.grant_type === 'authorization_code' &&
35+
typeof req.body.code === 'string' &&
36+
decodeURIComponent(req.body.code.replace(/\+/g, '%20')) === env.AUTHORIZATION_CODE
37+
) {
3538
return res.json(jwtResponse);
3639
} else if (req.body.grant_type === 'refresh_token' && req.body.refresh_token) {
3740
const payload = jwt.verify(req.body.refresh_token, env.JWT_SECRET_KEY) as JwtPayload;
3841
if (payload.type !== 'refresh_token') {
3942
throw new Error();
4043
}
4144
return res.json(jwtResponse);
45+
} else if(req.body.grant_type === 'client_credentials') {
46+
47+
const authHeader = req.headers.authorization;
48+
49+
if(!authHeader?.startsWith('Basic ')){
50+
throw new Error();
51+
}
52+
53+
const base64Credentials = authHeader.split(' ')[1];
54+
const decoded = Buffer.from(base64Credentials, 'base64').toString('utf-8');
55+
const [clientId, clientSecret] = decoded.split(':');
56+
57+
const decodedClientId = decodeURIComponent(clientId.replace(/\+/g, '%20'));
58+
const decodedClientSecret = decodeURIComponent(clientSecret.replace(/\+/g, '%20'));
59+
60+
if(decodedClientId === env.OAUTH_CLIENT_ID && decodedClientSecret === env.OAUTH_CLIENT_SECRET){
61+
return res.json(jwtResponse);
62+
} else {
63+
throw new Error();
64+
}
4265
}
4366

4467
throw new Error();

src/validationSchemas/auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ export const authorizeQuery: Schema = {
88
};
99

1010
export const generateAuthTokenBody: Schema = {
11-
grant_type: { isIn: { options: [['authorization_code', 'refresh_token']] } },
11+
grant_type: { isIn: { options: [['authorization_code', 'refresh_token', 'client_credentials']] } },
1212
};

0 commit comments

Comments
 (0)