lehh / nestjs-soap

Nestjs module wrapper for soap npm package
MIT License
21 stars 15 forks source link

Add WSSecurity auth method #20

Closed gmqz closed 2 years ago

gmqz commented 2 years ago

Hi team,

What we need: We are using this great package, but the 3rd party SOAP server changed the authentication method from Basic to WSSecurity. So I'm wondering if you are planning to add this authentication method...

Proposal: Keeping the SoapModuleOptions structure and add some optional properties to support other authentication methods that node-soap actually supports.

Add types to src/soap-module-options.type.ts

....
export type BasicAuth = {
  type?: string
  username: string;
  password: string;
};

export type WSSecurityType = {
  type: string
  username: string;
  password: string;
  options?: string;
};

export type WSSecurityOptions = {
  passwordType?: string;
  hasTimeStamp?: boolean;
  hasTokenCreated?: boolean;
  hasNonce?: boolean;
  mustUnderstand?: boolean,
  actor?: string;
};

export type SoapModuleOptions = {
  uri: string;
  clientName: string;
  auth?: BasicAuth | WSSecurityType;
  clientOptions?: IOptions;
};
....

Change how to set the security method in src/soap.service.ts

...
try {
  const client = await createClientAsync(options.uri, options.clientOptions);

  if (!options.auth) return client;

  const {username, password} = options.auth;

  const authMethod: ISecurity = options.auth.type === 'WSSecurity'
    ? new WSSecurity(username, password, (options.auth as WSSecurityType).options)
    : new BasicAuthSecurity(username, password);

  client.setSecurity(authMethod);

  return client;
} catch (err) {
...

Example

import { Module } from '@nestjs/common';
import { SoapModule, SoapModuleOptions } from 'nestjs-soap';
import { ConfigService, ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    SoapModule.forRootAsync(
      { 
        clientName: 'MY_SOAP_CLIENT',
        imports: [ConfigModule],
        inject: [ConfigService],
        useFactory: async (
          configService: ConfigService,
        ): Promise<SoapModuleOptions> => ({
          uri: configService.get<string>('soap.uri'),
          auth: {
            type: 'WSSecurity',
            username: configService.get<string>('soap.username'),
            password: configService.get<string>('soap.password'),
            options: {.....}
          },
        }),        
      }
    ),
  ],
})
export class ExampleModule {}

What do you think? I can create a PR if you want with this proposal....

Finally, thanks for the great work on this package.

lehh commented 2 years ago

Hello @gmqz,

Thanks a lot for the proposal! It seems fine to me, go ahead :). I'd just suggest a few improvements but I can comment when you open the PR.