Skip to content

Commit 903adaa

Browse files
feat: Allow private/public key to be override when signing/verifying
This allows you to pass the `privateKey` property in the options of sign, signAsync and `publicKey` in the verify, verifyAsync. It does not override a secretOrKeyProvider though only the `privateKey` and `publicKey` passed into the JwtModule. Resolves [#302](#302)
1 parent a9303a5 commit 903adaa

4 files changed

Lines changed: 51 additions & 3 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ The `JwtService` uses [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken)
154154

155155
#### jwtService.sign(payload: string | Object | Buffer, options?: JwtSignOptions): string
156156

157-
The sign method is an implementation of jsonwebtoken `.sign()`. Differing from jsonwebtoken it also allows an additional `secret` property on `options` to override the secret passed in from the module. It only overrides the `secret`, `publicKey` or `privateKey` though not a `secretOrKeyProvider`.
157+
The sign method is an implementation of jsonwebtoken `.sign()`. Differing from jsonwebtoken it also allows an additional `secret, privateKey, publicKey` property on `options` to override the secret passed in from the module. It only overrides the `secret`, `publicKey` or `privateKey` though not a `secretOrKeyProvider`.
158158

159159
#### jwtService.signAsync(payload: string | Object | Buffer, options?: JwtSignOptions): Promise\<string\>
160160

161161
The asynchronous `.sign()` method.
162162

163163
#### jwtService.verify\<T extends object = any>(token: string, options?: JwtVerifyOptions): T
164164

165-
The verify method is an implementation of jsonwebtoken `.verify()`. Differing from jsonwebtoken it also allows an additional `secret` property on `options` to override the secret passed in from the module. It only overrides the `secret`, `publicKey` or `privateKey` though not a `secretOrKeyProvider`.
165+
The verify method is an implementation of jsonwebtoken `.verify()`. Differing from jsonwebtoken it also allows an additional `secret, privateKey, publicKey` property on `options` to override the secret passed in from the module. It only overrides the `secret`, `publicKey` or `privateKey` though not a `secretOrKeyProvider`.
166166

167167
#### jwtService.verifyAsync\<T extends object = any>(token: string, options?: JwtVerifyOptions): Promise\<T\>
168168

lib/interfaces/jwt-module-options.interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ export interface JwtModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
3636

3737
export interface JwtSignOptions extends jwt.SignOptions {
3838
secret?: string | Buffer;
39+
privateKey?: string | Buffer;
3940
}
4041

4142
export interface JwtVerifyOptions extends jwt.VerifyOptions {
4243
secret?: string | Buffer;
44+
publicKey?: string | Buffer;
4345
}

lib/jwt.service.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,39 @@ describe('JWT Service', () => {
222222
);
223223
});
224224
});
225+
226+
describe('should use private/public key from options', () => {
227+
let jwtService: JwtService;
228+
229+
beforeAll(async () => {
230+
jwtService = await setup({
231+
...config,
232+
secretOrKeyProvider: undefined,
233+
secret: undefined
234+
});
235+
});
236+
237+
let privateKey = 'customPrivateKey';
238+
let publicKey = 'customPublicKey';
239+
240+
it('signing should use private key from options', async () => {
241+
expect(await jwtService.sign('random', { privateKey })).toBe(privateKey);
242+
});
243+
244+
it('signing (async) should use private key from options', async () => {
245+
expect(jwtService.signAsync('random', { privateKey })).resolves.toBe(
246+
privateKey
247+
);
248+
});
249+
250+
it('verifying should use public key from options', async () => {
251+
expect(await jwtService.verify('random', { publicKey })).toBe(publicKey);
252+
});
253+
254+
it('verifying (async) should use public key from options', async () => {
255+
expect(jwtService.verifyAsync('random', { publicKey })).resolves.toBe(
256+
publicKey
257+
);
258+
});
259+
});
225260
});

lib/jwt.service.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ export class JwtService {
9696
key: 'verifyOptions' | 'signOptions'
9797
): jwt.VerifyOptions | jwt.SignOptions {
9898
delete options.secret;
99+
if (key === 'signOptions') {
100+
delete (options as JwtSignOptions).privateKey;
101+
} else {
102+
delete (options as JwtVerifyOptions).publicKey;
103+
}
99104
return options
100105
? {
101106
...(this.options[key] || {}),
@@ -112,7 +117,13 @@ export class JwtService {
112117
): string | Buffer | jwt.Secret {
113118
let secret = this.options.secretOrKeyProvider
114119
? this.options.secretOrKeyProvider(secretRequestType, token, options)
115-
: options?.secret || this.options.secret || this.options[key];
120+
: options?.secret ||
121+
this.options.secret ||
122+
(key === 'privateKey'
123+
? (options as JwtSignOptions)?.privateKey || this.options.privateKey
124+
: (options as JwtVerifyOptions)?.publicKey ||
125+
this.options.publicKey) ||
126+
this.options[key];
116127

117128
if (this.options.secretOrPrivateKey) {
118129
this.logger.warn(

0 commit comments

Comments
 (0)