The constructor for HSMWalletMixin in HLF 1.4 doesn't have the correct variables - node.js

I'm trying to connect to an HSM using fabric-network V1.4.17 looking at the HSMWalletMixin constructor there are no options to tell the class the library label and pin.
Instead all these variables can be found in the X509WalletMixin.
Here's the code in the class:
export interface WalletMixin {} // tslint:disable-line:no-empty-interface
export class X509WalletMixin implements WalletMixin {
public static createIdentity(mspId: string, certificate: string, privateKey: string): Identity;
constructor(library?: string, slot?: string, pin?: string, userType?: string);
}
export class HSMWalletMixin implements WalletMixin {
public static createIdentity(mspId: string, certificate: string): Identity;
constructor();
}
So I tried creating an HSM Wallet using the X509WalletMixin like below, but it created a regular wallet instead.
const hsmWalletMixin = new X509WalletMixin('/path/to/lib/libCryptoki2_64.so', 'slot', 'pin');
const wallet = new FileSystemWallet(walletPath, hsmWalletMixin);
So, How can create an HSM Wallet then? are there some environment variables like in this tutorial Testing for Hardware Security Module via PKCS#11?
Thanks

Looking at the source code the implementation is correct
https://github.com/hyperledger/fabric-sdk-node/blob/4ca22aa1a70f464c3a5b9c259542aa7fee651061/fabric-network/lib/impl/wallet/hsmwalletmixin.js#L40
What is not correct are the type definitions which is the code snippet you have posted.
It's only going to be an issue if you are using typescript in which case you will just have to not use the HSMWalletMixin type to ensure typescript doesn't try to do any validation.

Related

How to send params of current request to the constructor of the service?

Update: I have fixed it by only supplying the pattern of the path of the collection, and creating a function that can parse the provided IDs and now the functions themselves create the collections when they are called upon and it also works with Typescript:)
Updated in the repository:
https://github.com/Darkbound/nestjs-firebase/tree/main/src/firebase
In the user service:
https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/user.service.ts
In the purchase transactions service: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.service.ts
In the purchase transactions controller: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.controller.ts#L14
Now the functionality works out of the box, the service class simply needs to extend the FirebaseCollectionService and give it the pattern of the path to the collection and thats it!
https://github.com/Darkbound/nestjs-firebase I have uploaded it into a repository, you only need to add .env with the keys for firebase admin.
And the specific example: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.service.ts
I have created a class that gives me the functionality to perform CRUD operations on firebase, so that I can just directly inherit from it for any of my CRUD resources, as the logic is again usually mostly the same. Just like Nestjs generator gives me all of the routes for it.
#Injectable()
export class UserService extends NestjsFirebase<User> {
constructor(#InjectFirebaseAdmin() firebase: FirebaseAdmin) {
super(firebase, "users");
// console.log(userId);
}
}
This works great, I can reuse that for any level 1 collection I have in firebase, however if I want to get into a nested collection on firebase, well thats a problem, because the path there needs to be dynamic and super(firebase, "this is no longer just users").
Say if I want to access the transactions of a user, so users/SomeUserIdXYZ/transactions, then the path is entirely dependent on the userId and is changing, therefor, I need to recreate the instance of the service (I simply need a new instance of the class), with a new path:
super(firebase, ["users", userId, "transactions"]
However with my still limited knowledge about Nestjs I know that everything in it basically is a Singleton and there is probably no way to do this? To get a new instance of the service, for every request that I have?
The solution that I can think of is, to handle that within my route functions, so if its a findTransactions:
#Get("users/:userId/transactions")
async findTransactions(#Param("userId") userId: string) {
return this.userService.findAll(`users/${userId}/transactions`);
}
And I am pretty sure that this will work, if I add a path argument to each of the functions, but this seems like coupling the Controller with what my Path in firebase should look like, instead I need to be able to give it just the params so that it can create its own path.
This is NestjsFirebase:
#Injectable()
class NestjsFirebase<T> {
constructor(#InjectFirebaseAdmin() private readonly firebase: FirebaseAdmin, private readonly collectionPath: string) {}
async findAll(userId: string): Promise<T> {
const db = new FirebaseCollectionService<T>(this.firebase, this.collectionPath);
return await db.findAll(userId);
}
}
export class FirebaseCollectionService<T> {
protected db: CollectionReference<T>;
constructor(firebase: FirebaseAdmin, collectionPath: string) {
super(firebase.db);
this.db = this.createCollectionPath(collectionPath);
}
public async findAll(id: string) {
... some logic to find all transactions ...
}
}

Cannot find module when using type from another module in class-validator

I'm using typescript on both frontend and backend, so I wanted to create a "shared types" package for them. For the backend I'm using nest.js and I recently ran into an issue with the class-validator package.
In my shared types package I created the following enum-like type (since enums itself don't seem to be working if they are being used from a node module):
export const MealTypes = {
BREAKFAST: 'Breakfast',
LUNCH: 'Lunch',
DINNER: 'Dinner',
SNACK: 'Snack'
} as const;
export type ObjectValues<T> = T[keyof T];
export type MealType = ObjectValues<typeof MealTypes>;
I've installed the module locally using npm i and I'm able to import the type in my backend like this:
import { MealType, MealTypes } from '#r3xc1/shared-types';
Since I am not able to use this constant for the IsEnum class validator, I wrote my own:
#ValidatorConstraint({ name: 'CheckEnum', async: false })
export class CheckEnumValidator implements ValidatorConstraintInterface {
validate(value: string | number, validationArguments: ValidationArguments) {
return Object.values(validationArguments.constraints[0]).includes(value);
}
defaultMessage(args: ValidationArguments) {
return `Must be of type XYZ`;
}
}
and then I'm using it in a DTO class like this:
export class CreateMealDTO {
#Validate(CheckEnumValidator, [MealTypes])
#IsNotEmpty()
meal_type: MealType;
}
But as soon as I add the #Validate(...) I get the following error on start:
Error: Cannot find module '#r3xc1/shared-types'
It only does this, if I am passing a type that has been imported from a node module into a validator. It also happens with other validators like IsEnum.
I'm not really sure why this error is happening and I appreciate any hints or help!

NestJs -Pass in path to route handler via Dynamic Module

Im working on a team that has a bunch of services so we have a npm package that contains code shared between the services.
We have a Health check module that sets the path to globalPrefix/health. Im attempting to make this value configurable in a maintainable way.
#Injectable()
#Controller()
export class HealthController {
private readonly healthCheckOptions: HealthConfigurationOptions;
private readonly url: string;
constructor(
#Inject('CONFIGURATION_OPTIONS') private options: HealthConfigurationOptions,
private readonly healthService: HealthService,
) {
this.healthCheckOptions = options || {}
this.url = options.url
}
#Get(this.url)
async healthHandler(): Promise<HealthDto | TmoHttpException> {
return this.healthService.getStatus();
}
}
My idea was to create a Dynamic Module that can take a path as an option. In the example above There is a Dynamic Health Module that accepts an options object. But it seems like during compilation the route handler is set before the class is constructed meaning that i cannot use this.url like #Get(this.url) because there is no this yet.
At this point Im a bit stumped and haven't found anything online doing what I need.
Reflect.defineMetadata(PATH_METADATA, 'my_custom_path', MyController);
while registering your custom dynamic module will change the path of your controller. however there are still issues with this approach.
see here: https://github.com/nestjs/nest/issues/1438#issuecomment-1324011241

NestJS class-validators on incoming requests using interface

I need to use an interface through class-validator to validate the incoming form for a specific field in the incoming request body.
The interface:
export enum Fields {
Full_Stack_Dev = 'full stack dev',
Frontend_Dev = 'frontend dev',
Backend_Dev = 'backend dev',
}
export interface Experience {
field: Fields;
years: number;
}
And here is the DTO Class:
#IsEnum(Languages)
languages: Languages[];
experience: Experience[]; // 👈 Not sure which decorator to use for interfaces
Okay after doing a lot of research, I found a workaound for this:
First of all, Interfaces CANNOT be used directly. Officially declared by class-validators issue here
This is what I did:
Changed the interface into a separate class and added validation on its properties
class ExperienceDto {
#IsEnum(Fields)
field: Fields;
#IsNumber()
years: number;
}
Then used this class as type to validate Array of Objects in the ACTUAL DTO CLASS (not the above one)
#ArrayNotEmpty()
#ArrayMinSize(1)
#ArrayMaxSize(3)
#ValidateNested({ each: true })
#Type(() => ExperienceDto) // imported from class-transformer package
experience: ExperienceDto[];

Why does JHipster generate Interfaces for Angular model objects?

Why does JHipster generate interfaces for each Angular model object?
e.g.
export interface IStudent {
id?: number;
studentIdentifier?: string;
firstName?: string;
lastName?: string;
}
export class Student implements IStudent {
constructor(
public id?: number,
public studentIdentifier?: string,
public firstName?: string,
public lastName?: string,
) {}
}
I cannot find the original discussion but in my understanding, this is because of the way how interfaces work in TypeScript, which is a little different than in Java. They not just describe how a class should look like by defining its method, but also which fields should be present. So you can define, how a JSON from somewhere should look like. Like a POJO. Or a POTO (plain old TypeScript object) :)
By example, you could do that:
let student: IStudent = { id: 123, studentIdentifier: '...',...}
and TS would check if your provided object satisfies the defined structure of student. When you get an object out from the API, you just map a JSON directly this way, so there is no class in between. From the other side, it's more handy to work with classes rather than interfaces, when building objects of IStudent directly. As it also satisfies IStudent, you can make just
let student: IStudent = new Student(123, '...', ..)
which is shorter.
You could rely also on my first snippet (this is how ionic does it, btw. Using interfaces as POJOs/POTOs). Using classes only in TS leads to a bad developer experience IMHO.
Hope that helps a little bit out

Resources