@naturalcycles/nodejs-lib
Version:
Standard library for Node.js
66 lines (65 loc) • 2.26 kB
JavaScript
import { _assert } from '@naturalcycles/js-lib/error/assert.js';
import { _errorDataAppend } from '@naturalcycles/js-lib/error/error.util.js';
import jsonwebtoken from 'jsonwebtoken';
export { jsonwebtoken };
// todo: define JWTError and list possible options
// jwt expired (TokenExpiredError)
// jwt invalid
// jwt token is empty
/**
* Wraps popular `jsonwebtoken` library.
* You should create one instance of JWTService for each pair of private/public key.
*
* Generate key pair like this.
* Please note that parameters should be different for different algorithms.
* For ES256 (default algo in JWTService) key should have `prime256v1` parameter:
*
* openssl ecparam -name prime256v1 -genkey -noout -out key.pem
* openssl ec -in key.pem -pubout > key.pub.pem
*/
export class JWTService {
cfg;
constructor(cfg) {
this.cfg = cfg;
}
sign(payload, schema, opt = {}) {
_assert(this.cfg.privateKey, 'JWTService: privateKey is required to be able to verify, but not provided');
schema?.validate(payload);
return jsonwebtoken.sign(payload, this.cfg.privateKey, {
algorithm: this.cfg.algorithm,
noTimestamp: true,
...this.cfg.signOptions,
...opt,
});
}
verify(token, schema, opt = {}, publicKey) {
_assert(this.cfg.publicKey, 'JWTService: publicKey is required to be able to verify, but not provided');
try {
const data = jsonwebtoken.verify(token, publicKey || this.cfg.publicKey, {
algorithms: [this.cfg.algorithm],
...this.cfg.verifyOptions,
...opt,
});
schema?.validate(data);
return data;
}
catch (err) {
if (this.cfg.errorData) {
_errorDataAppend(err, {
...this.cfg.errorData,
});
}
throw err;
}
}
decode(token, schema) {
const data = jsonwebtoken.decode(token, {
complete: true,
});
_assert(data?.payload, 'invalid token, decoded value is empty', {
...this.cfg.errorData,
});
schema?.validate(data.payload);
return data;
}
}