2022-10-24 05:14:17 +00:00
|
|
|
import * as plugins from './smartjwt.plugins.js';
|
2019-10-01 16:04:43 +00:00
|
|
|
|
2024-08-26 19:49:48 +00:00
|
|
|
// Define the IWithJwt interface with a constraint that T must be an object
|
|
|
|
export type IObjectWithJwt<T extends object> = T & { jwt: string };
|
|
|
|
|
2019-10-01 16:04:43 +00:00
|
|
|
/**
|
2019-10-01 17:58:53 +00:00
|
|
|
* A class to create and validate JWTs and their keys
|
2019-10-01 16:04:43 +00:00
|
|
|
*/
|
2021-02-09 10:26:42 +00:00
|
|
|
export class SmartJwt<T extends object = any> {
|
2019-10-01 16:04:43 +00:00
|
|
|
public smartcryptoInstance = new plugins.smartcrypto.Smartcrypto();
|
|
|
|
public publicKey: plugins.smartcrypto.PublicKey;
|
|
|
|
public privateKey: plugins.smartcrypto.PrivateKey;
|
|
|
|
|
2019-10-01 18:03:36 +00:00
|
|
|
constructor() {}
|
2019-10-01 16:04:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* creates a JWT
|
|
|
|
*/
|
2021-02-09 10:26:42 +00:00
|
|
|
public async createJWT(payloadArg: T) {
|
2019-10-01 17:07:59 +00:00
|
|
|
return plugins.jsonwebtoken.sign(payloadArg, this.privateKey.toPemString(), {
|
2021-02-20 18:02:53 +00:00
|
|
|
algorithm: 'RS256',
|
2019-10-01 17:07:59 +00:00
|
|
|
});
|
2019-10-01 16:04:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* checks a JWT
|
|
|
|
*/
|
2021-02-09 10:26:42 +00:00
|
|
|
public async verifyJWTAndGetData(jwtArg: string): Promise<T> {
|
|
|
|
const result = plugins.jsonwebtoken.verify(jwtArg, this.publicKey.toPemString(), {
|
2021-02-20 18:02:53 +00:00
|
|
|
algorithms: ['RS256'],
|
2019-10-01 17:07:59 +00:00
|
|
|
});
|
2021-02-09 10:26:42 +00:00
|
|
|
return result as any;
|
2019-10-01 17:07:59 +00:00
|
|
|
}
|
2019-10-01 16:04:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* sets a private key to create jwts with
|
|
|
|
*/
|
|
|
|
public async setPrivateKey(privateKey: plugins.smartcrypto.PrivateKey) {
|
|
|
|
this.privateKey = privateKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-10-01 18:03:36 +00:00
|
|
|
* sets a public key
|
2019-10-01 16:04:43 +00:00
|
|
|
*/
|
|
|
|
public async setPublicKey(publicKey: plugins.smartcrypto.PublicKey) {
|
|
|
|
this.publicKey = publicKey;
|
|
|
|
}
|
|
|
|
|
2019-10-01 17:58:53 +00:00
|
|
|
/**
|
|
|
|
* gets the currently set kaypair as json
|
|
|
|
*/
|
2024-02-13 00:18:57 +00:00
|
|
|
public getKeyPairAsJson(): plugins.tsclass.network.IJwtKeypair {
|
2019-10-01 17:58:53 +00:00
|
|
|
return {
|
|
|
|
privatePem: this.privateKey.toPemString(),
|
2021-02-20 18:02:53 +00:00
|
|
|
publicPem: this.publicKey.toPemString(),
|
2019-10-01 17:58:53 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the currently set keypair as json
|
|
|
|
*/
|
2024-02-13 00:18:57 +00:00
|
|
|
public setKeyPairAsJson(jsonKeyPair: plugins.tsclass.network.IJwtKeypair) {
|
2019-10-01 17:58:53 +00:00
|
|
|
this.privateKey = plugins.smartcrypto.PrivateKey.fromPemString(jsonKeyPair.privatePem);
|
|
|
|
this.publicKey = plugins.smartcrypto.PublicKey.fromPemString(jsonKeyPair.publicPem);
|
|
|
|
}
|
|
|
|
|
2019-10-01 16:04:43 +00:00
|
|
|
/**
|
|
|
|
* creates a new keypair
|
|
|
|
*/
|
|
|
|
public async createNewKeyPair() {
|
|
|
|
const keypair = await this.smartcryptoInstance.createKeyPair();
|
|
|
|
this.setPrivateKey(keypair.privateKey);
|
|
|
|
this.setPublicKey(keypair.publicKey);
|
|
|
|
}
|
2020-03-28 22:48:17 +00:00
|
|
|
|
2021-02-09 10:26:42 +00:00
|
|
|
/**
|
|
|
|
* when you just want to validate something
|
|
|
|
* @param publicPemKey
|
|
|
|
*/
|
|
|
|
public setPublicPemKeyForVerification(publicPemKey: string) {
|
|
|
|
this.publicKey = plugins.smartcrypto.PublicKey.fromPemString(publicPemKey);
|
|
|
|
}
|
|
|
|
|
2020-03-28 22:48:17 +00:00
|
|
|
public async init() {
|
|
|
|
await this.createNewKeyPair();
|
|
|
|
}
|
2024-08-26 19:49:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public isObjectWithJwt<T extends object>(
|
|
|
|
object: unknown,
|
|
|
|
): object is IObjectWithJwt<T> {
|
|
|
|
return (
|
|
|
|
typeof object === 'object' &&
|
|
|
|
object !== null &&
|
|
|
|
'jwt' in object &&
|
|
|
|
typeof (object as IObjectWithJwt<T>).jwt === 'string'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public jwtObjectGuard = new plugins.smartguard.Guard(async (dataArg: IObjectWithJwt<any>) => {
|
|
|
|
const jwtData = this.verifyJWTAndGetData(dataArg.jwt);
|
|
|
|
// check all other properties wether they match with jwtData
|
|
|
|
for (const key in dataArg) {
|
|
|
|
if (key !== 'jwt') {
|
|
|
|
if (jwtData[key] !== dataArg[key]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}, {
|
|
|
|
name: 'jwtObjectGuard',
|
|
|
|
failedHint: 'is not a valid jwt object',
|
|
|
|
})
|
2019-10-01 18:03:36 +00:00
|
|
|
}
|