Show / Hide Table of Contents

    DocuWorld 2019 SDK Workshop - Code Guide

    Dominik Peukert - Director Research & Development - DocuWare GmbH

    Content description of projects

    The workshop was held with DocuWare Version 7.1.
    Both services also compatible with older versions except basic authentication part, this is only available since 7.1.

    You can start a new project or download the project skeleton here:

    http://go.docuware.com/docuworldsdk2019

    Node.js Valdiation Service - REST

    This project will be a simple example how to work with DocuWare Validation. The service will contain a POST method for validating if the a single invoice is already available in an external data source.

    Node.js Enhancement Service - SOAP

    This project contains the logic of enhancing the external datasource with the DWDocid of a stored DocuWare document. This will be done by a Workflow containing an Web Serice Activity.

    DocuWare System Layout

    • A file cabinet with following layout is needed:

      Name Type
      InvoiceNumber Number
      Company Text
      Amount Decimal
      Comment Text
    • Variables in Workflow:

      Name Type
      DWDocid Text
      InvoiceNumber Number
      Result Text
      Result_Message Text

      Also don't forget to assign DWDocid and Invoice number in the beginning of your DocuWare Workflow. The 2 result variables has to be filled by the Workflow Web Service Activity.

    Base setup (IFNEWPROJECT)

    1. Go to project folder and choose {ProjectFolder}
       -FakeDatabase
       -REST_ValidationService
       -SOAP_EnhancmentService
      
    2. "npm init"
      1. Description: "DocuWorld Sample: {ProjectName}"
      2. Main: "index.js"
      3. Add "private":true
      4. Add "start": "node ./dist/index.js", to "scripts" section
    3. Add typescript: "npm i typescript" (local installation)
    4. Add typescript support: "npm i -D typescript @types/node"
    5. Init tsconfig.json: "npx tsc --init" (Package runner - available since npm 5.2.0)
      1. Add "outDir" :"dist" and "sourceMap" : "true"
    6. Add "index.ts":
       export function hello(): string{
           return 'Hello World!';
       }
      
       hello();
      
    7. Enable file watcher: "npx tsc -w"
      Alternativly you can use "strg + shift + B" in VS Code to choose tsconfig

    Validation Service

    Snapshot 0: REST Initial State

    1. (IFNEWPROJECT) Get express for building up service: "npm i express --save" (--save sets it as dependency to the package.json)
    2. (IFNEWPROJECT) To start the application use "npm start" (Firewall YES!)
    3. Add typescript support for express: "npm i -D typescript @types/express"
    4. Init the express in "index.ts":
      //express parts
      import express from "express";
      import bodyParser from 'body-parser';
      const app = express();
      const port = 1337;
      
      //enable json bodyparsing
      app.use(bodyParser.json());
      
      //start server listening
      app.listen(port, () => {
          console.log(`Server is running on port: ${port}`);
      });
      

    Snapshot 1: REST Express Base Ready

    1. Add GET request for returning dummy first:
       //define GET for testing  http://localhost:1337/status
      app.get("/status", (req: any, res: any, next: any) => {
          res.json({"status":"Up and running"});
      });
      
    2. Try with http://localhost:1337/status you'll get
      {"status":"Service is up and running!"}
      

    Snapshot 2: REST Express Test Ready

    Prepare the dummy JSON database

    1. (IFNEWPROJECT) Go to root directory

      -FakeDatabase
          --db.json
      -REST_ValidationService
      -SOAP_EnhancmentService
      

      and create the db.json:

      {
          "invoices": [
              {
                  "InvoiceNumber": 1,
                  "Company": "John Doe Inc",
                  "Amount": 30,
                  "DWDOCID": null,
                  "ValidtionSuccess": false,
                  "EnhancementSuccess": false
              },
              {
                  "InvoiceNumber": 2,
                  "Company": "Peters Engineering",
                  "Amount": 5,
                  "DWDOCID": null,
                  "ValidtionSuccess": false,
                  "EnhancementSuccess": false
              },
              {
                  "InvoiceNumber": 3,
                  "Company": "DocuWorld EMEA GmbH",
                  "Amount": 1337,
                  "DWDOCID": null,
                  "ValidtionSuccess": false,
                  "EnhancementSuccess": false
              }
          ]
      }
      
    2. (IFNEWPROJECT) Install lowdb: "npm i lowdb --save" (https://github.com/typicode/lowdb)

    3. (IFNEWPROJECT) Add typescript support for lowdb: "npm i -D typescript @types/lowdb"

    4. (IFNEWPROJECT) Init lowdb:

      //lowdb parts
      import low from 'lowdb';
      import FileAsync from 'lowdb/adapters/FileAsync';
      let lowdbFileAdapter: AdapterAsync = new FileAsync<DocuWareWorkshop.IJsonDBSchema>("../FakeDatabase/db.json");
      
    5. Start db and refactor express:

      //Create database instance
      lowDb(lowdbFileAdapter)
          .then((db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>) => {
              //define GET for status http://localhost:1337/status
              app.get("/status", (req: any, res: any, next: any) => {
                  res.json({"status":"Service is up and running!"});
              });
      
          })
          .then(() => {
              //start server listening
              app.listen(port, () => {
                  console.log(`Server is running on port: ${port}`);
              });
          })
      

    Snapshot 3: REST LowDb Base Ready

    Prepare for Validation

    DocuWare Validation Schemas available here: https://github.com/DocuWare/Validation-NodeJS-samples

    1. (IFNEWPROJECT) Add typescript support for json-schema: "npm i -D typescript @types/json-schema"
    2. Create class and method to build validation response json, see DocuWareValidationContract.d.ts:
      function CreateValidationFeedback(type: DocuWareValidation.FeedbackType, reason: string): DocuWareValidation.IValidationFeedback {
          return new DWValidationFeedback(type, reason);
      }
      
      class DWValidationFeedback implements DocuWareValidation.IValidationFeedback {
          constructor(public Status: DocuWareValidation.FeedbackType, public Reason: string) {
          }   
      }
      
    3. Add validation method to POST and rename it:
          //define POST for validation http://localhost:1337/validate
          app.post("/validate", (req: any, res: any, next: any) => {
      
          });
      
    4. Use newly created method and call it in GET:
          //define POST for validation http://localhost:1337/validate
          app.post("/validate", (req: any, res: any, next: any) => {
      
              let result = CreateValidationFeedback(DocuWareValidation.FeedbackType.OK, "Alright!");
              res.json(result);
          });
      

    Snapshot 4: REST Validation Method Prepared Ready

    Call fake database and do the validation

    1. Parse the body of validate POST method:

              //define POST for validation http://localhost:1337/validate
              app.post("/validate", (req: any, res: any, next: any) => {
                  try{
                      //Get body from request
                      let validationBody: DocuWareValidation.IValidationBody = req.body;
      
                  } catch(error){
                      console.log(error);
                  }
      
    2. Do simple checks on body object:

      function validateJsonBody(jsonBody: jsonSchema.JSONSchema4):boolean{
          //Check if any values exist
          if (!validationBody.Values || validationBody.Values.length === 0) {
              throw new Error("No index values found!");
          }
      
          //and e.g. proof you getting called by the right organization (in case you have more than one)
          if (validationBody.OrganizationName !== "Peters Engineering") {
              throw new Error(`The validation for organization ${validationBody.OrganizationName} is not supported!`);
          }
      }
      
          try {
              //Get body from request
              let validationBody: DocuWareValidation.IValidationBody = req.body;
      
              //Check if layout looks like desired
              validateJsonBody(validationBody);
      
    3. Get index value from the request body:

      function getFieldFromBodyByName(validationBody: DocuWareValidation.IValidationBody, dwFieldName: string): DocuWareValidation.IValidationField {
          let indexField = validationBody.Values.find((x: DocuWareValidation.IValidationField) => {
              return x.FieldName.toLocaleLowerCase() === dwFieldName.toLocaleLowerCase();
          });
      
          if (!indexField) {
              throw new Error(`${dwFieldName} not available`);
          }
      
          return indexField;
      }
      
    4. Call new method with "INVOICENUMBER" (naming of your DocuWare DB Field):

          //Get the invoice number
          let invoiceField = getFieldFromBodyByName(validationBody, "invoicenumber");
          if (invoiceField.Item !== null) {
      
      
          } else {
              throw new Error("No invoice number provided!");
          }
      
      
    5. Get database entry and check if it exists:

      function getEntryFromDatabase(db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>, invoiceNumber: number): DocuWareWorkshop.IDbInvoiceEntry{
          let results: LoDashExplicitAsyncWrapper<DocuWareWorkshop.IDbInvoiceEntry[]> = db.get('invoices');
          let databaseInvoiceEntry = <DocuWareWorkshop.IDbInvoiceEntry>results
              .find({ InvoiceNumber: invoiceNumber })
              .value();
      
          return databaseInvoiceEntry;
      }
      
          if (invoiceField.Item !== null) {
              //lockup database by validation field invoice number
              let databaseInvoiceEntry: DocuWareWorkshop.IDbInvoiceEntry = getEntryFromDatabase(db, invoiceField.Item as number);
      
              //check if there is something in the database
              if (databaseInvoiceEntry) {
      
              } else {
                  throw new Error("Invoice entry not foudn in external in database!");
              }
      
    6. In case everything is fine, set validationsuccess to true in database and return positive feedback result:

      function updateDataBase(db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>, invoiceNumber: number): Promise<DocuWareWorkshop.IDbInvoiceEntry> {
          return db.get('invoices')
              .find({ InvoiceNumber: invoiceNumber })
              .assign({ ValidtionSuccess: true })
              .write();
      }
      
          //check if there is something in the database
          if (databaseInvoiceEntry) {
              //update database and set validation boolean to true
              let promise: Promise<DocuWareWorkshop.IDbInvoiceEntry> = updateDataBase(db, invoiceField.Item as number)
              promise
                  .then((updatedDatabaseInvoiceEntry: DocuWareWorkshop.IDbInvoiceEntry) => {
                      console.info(updatedDatabaseInvoiceEntry);
                      return res.json(CreateValidationFeedback(DocuWareValidation.FeedbackType.OK, "Invoice found in database. OK!"));
                  });
      
    7. Add better catch handling:

          } catch (error) {
               return res.json(CreateValidationFeedback(DocuWareValidation.FeedbackType.Failed, `${error.message}`));
          }
      

    Snapshot 5: REST Validation Without Auth Ready

    Build executable

    1. (IFNEWPROJECT) Install lowdb: "npm i pkg --save" (https://github.com/zeit/pkg)
    2. (IFNEWPROJECT) Add to package.json:
      "bin": "./dist/index.js",
      .
      .
      . 
      "pkg": {
          "scripts": "dist/**/*.js",
          "targets": [
          "node6"
          ]
      }
      
    3. Run npx pkg package.json
    4. You'll find a rest_validationservice.exe in your root directory

    Add basic authentication to REST (Supported with DocuWare 7.1)

    1. (IFNEWPROJECT) Install basic authentication for express: "npm i express-basic-auth --save"
    2. (IFNEWPROJECT) Add basicAuthentication:
      import basicAuth from 'express-basic-auth';
      
    3. "Register" it:
      //enable basic auth
      app.use(basicAuth({
          users: {
              "admin":"secret"
          }
      }));
      

    Snapshot 6: REST Validation Including Auth Ready

    SOAP Service

    Snapshot 0: SOAP inital state (index.ts)

    Testing of the SOAP functionality can be done easily with the WCF Test Client or POSTMan

    1. (IFNEWPROJECT) Get express for building up service: "npm i express --save" (--save sets it as dependency to the package.json)
    2. (IFNEWPROJECT) To start the application use "npm start"
    3. Init the express in index.ts:
          //express imports
          import express, { Application, NextFunction, Request, Response } from "express";
          import bodyParser from "body-parser";
          import basicAuth from "express-basic-auth";
      
          //express setup
          let app: Application = express();
          let port: number = 1338;
      
          app.use(bodyParser.raw({
              type: () => {
                  return true;
              },
              limit: "5mb"
          }));
      
          //In case something goes completely wrong
          app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
              console.error(err.stack);
              res.status(500).send(`Something broke: ${err.message}`);
          });
      
    4. (IFNEWPROJECT) Add typescript support for express: "npm i -D typescript @types/express"

    Snapshot 1: SOAP Express Base Ready

    1. (IFNEWPROJECT) Install soap: "npm i soap --save" + dependency "npm i bluebird --save"

    2. (IFNEWPROJECT) Install types for bluebird, types of soap already there: "npm i -D @types/bluebird"

    3. (IFNEWPROJECT) Add soap_service.wsdl:

      <?xml version="1.0" encoding="UTF-8"?>
      <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
          xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" 
          xmlns:wsa10="http://www.w3.org/2005/08/addressing" 
          xmlns:tns="http://tempuri.org/" 
          xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" 
          xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
          xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" 
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
          xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
          xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
          xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
          xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="EnhancementService" targetNamespace="http://tempuri.org/">
          <wsdl:types>
              <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
                  <xs:element name="SyncDocid">
                      <xs:complexType>
                          <xs:sequence>
                              <xs:element minOccurs="0" maxOccurs="1" name="dwdocid" type="xs:string"/>
                              <xs:element minOccurs="0" maxOccurs="1" name="invoiceNumber" type="xs:int"/>
                          </xs:sequence>
                      </xs:complexType>
                  </xs:element>
                  <xs:element name="SyncDocidResponse">
                      <xs:complexType>
                          <xs:sequence>
                              <xs:element minOccurs="1" maxOccurs="1" name="Success" type="xs:boolean"/>
                              <xs:element minOccurs="1" maxOccurs="1" name="Message" type="xs:string"/>
                          </xs:sequence>
                      </xs:complexType>
                  </xs:element>
              </xs:schema>
          </wsdl:types>
          <wsdl:message name="EnhancementService_SyncDocid_InputMessage">
              <wsdl:part name="parameters" element="tns:SyncDocid"/>
          </wsdl:message>
          <wsdl:message name="EnhancementService_SyncDocid_OutputMessage">
              <wsdl:part name="parameters" element="tns:SyncDocidResponse"/>
          </wsdl:message>
          <wsdl:portType name="EnhancementService">
              <wsdl:operation name="SyncDocid">
                  <wsdl:input wsaw:Action="http://tempuri.org/EnhancementService/SyncDocid" message="tns:EnhancementService_SyncDocid_InputMessage"/>
                  <wsdl:output wsaw:Action="http://tempuri.org/EnhancementService/SyncDocidResponse" message="tns:EnhancementService_SyncDocid_OutputMessage"/>
              </wsdl:operation>
          </wsdl:portType>
          <wsdl:binding name="BasicHttpBinding_EnhancementService" type="tns:EnhancementService">
              <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
              <wsdl:operation name="SyncDocid">
                  <soap:operation soapAction="http://tempuri.org/EnhancementService/SyncDocid" style="document"/>
                  <wsdl:input>
                      <soap:body use="literal"/>
                  </wsdl:input>
                  <wsdl:output>
                      <soap:body use="literal"/>
                  </wsdl:output>
              </wsdl:operation>
          </wsdl:binding>
          <wsdl:service name="EnhancementService">
              <wsdl:port name="BasicHttpBinding_EnhancementService" binding="tns:BasicHttpBinding_EnhancementService">
                  <soap:address location="http://localhost:1338/EnhancementService"/>
              </wsdl:port>
          </wsdl:service>
      </wsdl:definitions>
      
    4. Setup service, check also DocuWareWorkshopSampleContracts.d.ts:

      function buildService(db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>): IServices {
          return {
              EnhancementService: {
                  BasicHttpBinding_EnhancementService: {
                      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
                          return {
                              Success: true,
                              Message: "test"
                          };
                      }
                  }
              }
          };
      }
      
    5. Read out the .wsdl file:

      import fs from "fs";
      
      //Read wsdl definition
      var wsdlXML = fs.readFileSync("soap_service.wsdl", "utf8");
      
    6. Get service, define listening GET + POST:

      //SOAP parts
      import soap from "soap";
      
      //Get the service definition
      let soapService : IServices = buildService(db);
      
      //GET /EnhancementService returns wsdl file 
      app.get("/EnhancementService", (req: any, res: any, next: any) => {
          res.set("Content-Type", "text/xml");
          res.send(wsdlXML);
      });
      
      //Start listening
      app.listen(1338, () => {
          // POST /EnhancementService route will be handled by soap module 
          let theService = soap.listen(app, "/EnhancementService", soapService, wsdlXML);
      
      });
      
    7. (IFNEWPROJECT) Install lowdb: "npm i lowdb --save" (https://github.com/typicode/lowdb)

    8. (IFNEWPROJECT) Add typescript support for lowdb: "npm i -D typescript @types/lowdb"

    9. Init lowdb:

      //init database
      lowDb(lowdbFileAdapter)
          .then((db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>) => {
              try{
      
                  //Read wsdl definition
                  var wsdlXML = fs.readFileSync("soap_service.wsdl", "utf8");
      
                  //Get the service definition
                  let soapService : IServices = buildService(db);
      
                  //GET /EnhancementService returns wsdl file 
                  app.get("/EnhancementService", (req: any, res: any, next: any) => {
                      res.set("Content-Type", "text/xml");
                      res.send(xml);
                  });
      
                  //Start listening
                  app.listen(1338, () => {
                      // POST /EnhancementService route will be handled by soap module 
                      let theService = soap.listen(app, "/EnhancementService", soapService, xml);
      
                      //do logging
                      theService.log = (type: string, data: any) => {
                          console.log(`${type} || ${data}`);
                      };
                  });
      
      
              }catch(error){
                  console.error(error);
              }
      });
      
    10. Create SoapResult class and build it by method:

      class EnhancmentSoapResult implements DocuWareWorkshop.ISoapResult{
          constructor(public Success: boolean, public Message: string) {
          }   
      }
      
      function buildResponse(success: boolean, message: string): DocuWareWorkshop.ISoapResult {
          //Success depending logging
          (success) ? console.info(`${success}: ${message}`) : console.error(`${success}: ${message}`);
      
          return new EnhancmentSoapResult(success, message);
      }
      
      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
          callback(buildResponse(true, "OK"));
      }
      

    Snapshot 2: SOAP Service Base Ready

    1. Write validation of soap arguments function and use it:

      function validateArguments(soapArguments: DocuWareWorkshop.ISoapArguments){
          if(!soapArguments){
              throw new Error(`No data provided!`);
          }else if(soapArguments.invoiceNumber === null || soapArguments.dwdocid === null){
              throw new Error(`Incomplete data provided!`)
          }
      }
      
      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
          try {     
              //validate the arguments
              validateArguments(args);
      
    2. Get entry from database:

      function getEntryFromDatabase(db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>, invoiceNumber: number): DocuWareWorkshop.IDbInvoiceEntry{
          let results: LoDashExplicitAsyncWrapper<DocuWareWorkshop.IDbInvoiceEntry[]> = db.get("invoices");
          let databaseInvoiceEntry = <DocuWareWorkshop.IDbInvoiceEntry>results
              .find({ InvoiceNumber: invoiceNumber })
              .value();
      
          return databaseInvoiceEntry;
      }
      
      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
          try {     
              .
              .
              //lockup database arguments invoice number
              let databaseInvoiceEntry: DocuWareWorkshop.IDbInvoiceEntry = getEntryFromDatabase(db, args.invoiceNumber);
      
    3. Do real enhancement: Get database entry and check if it was not syncronized earlier:

      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
          try {     
              .
              .
              //check if there is something in the database
              if (databaseInvoiceEntry) {
                  //Deny sync in case it is already flagged 'true'
                  if (databaseInvoiceEntry.EnhancementSuccess === true) {
                      throw new Error("DWDOCID already syncronized. Syncronized ID: " + databaseInvoiceEntry.DWDOCID);
                  } else {
      
    4. In case everything is fine, set EnhancementSuccess to true, and write DWDOCID to external database and return positive feedback response:

          function updateDataBase(db: LowdbAsync<DocuWareWorkshop.IJsonDBSchema>, soapArguments: DocuWareWorkshop.ISoapArguments): Promise<DocuWareWorkshop.IDbInvoiceEntry> {
              return db.get("invoices")
                  .find({ InvoiceNumber: soapArguments.invoiceNumber})
                  .assign({ EnhancementSuccess: true, DWDOCID: soapArguments.dwdocid  })
                  .write();
          }
      
      
      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
          try {    
              .
              .
              .
                  if (databaseInvoiceEntry.EnhancementSuccess === true) {
                      throw new Error("DWDOCID already syncronized. Syncronized ID: " + databaseInvoiceEntry.DWDOCID);
                  }
                  else {
                      //syncronize dwdocid and set enhancement to true
                      let promise: Promise<DocuWareWorkshop.IDbInvoiceEntry> = updateDataBase(db, args);
                      promise
                          .then((updatedEntry: DocuWareWorkshop.IDbInvoiceEntry) => {
                              console.info(updatedEntry);
                              callback(buildResponse(true, "DWDOCID syncronized!"));
                          });
                      }
                  }  else {
                       throw new Error(`Invoice ${args.invoiceNumber} not found in external database!`);
                  }
      
    5. Finish try catch:

      SyncDocid: (args: DocuWareWorkshop.ISoapArguments, callback: any) => {
          try {  
              .
              .
              .
          } catch (error) {
              callback(buildResponse(false, error.message));   
          }
      
      

    Snapshot 3: SOAP Service Without Auth Ready

    Build executable

    1. Install lowdb: "npm i pkg --save" (https://github.com/zeit/pkg)
    2. Add to package.json:
      "bin": "./dist/index.js",
      .
      .
      . 
      "pkg": {
          "scripts": "dist/**/*.js",
          "targets": [
          "node6"
          ]
      }
      
    3. Run npx pkg package.json
    4. You'll find a soap_enhancementservice.exe in your root directory

    Add basic authentication to SOAP (Supported with DocuWare 7.1)

    We could use same like on rest, just for demo we build our own

    1. Create custom error response:
          function sendNotAuthorizedResponse(req: Request, res: Response){
              console.error(`'${req.url}' Request blocked, no or wrong authentication provided!`);
      
              res.set("WWW-Authenticate", "Basic realm=Authorization Required");
              res.sendStatus(401);
          }
      
    2. Add custom auth function:
       //custom authentication
       let customAuth = function(req: Request, res: Response, next: NextFunction){
      
           //get auth header value
           let authorizationHeaderValue = req.headers["authorization"];
      
           if(!authorizationHeaderValue){
               sendNotAuthorizedResponse(req, res);
               return;
           }
      
           //match with regex: 'Basic {base64encodedCredentials}'
           let regex: RegExp = /[Bb]asic ([\s\S]+)/i;
           let result : RegExpMatchArray | null = authorizationHeaderValue.match(regex);
      
           //regex successfully executed
           if(result){
               //get result string
               let base64EncodiedCredentials = result[1]; //Explanation: Authorization value could be 'Basic SGVsbG86VGhlcmU='
                                                       // so it splits like this Basic -> result[0], SGVsbG86VGhlcmU= -> result[1]
      
               //Decode from base64 to string
               let buffer = Buffer.from(base64EncodiedCredentials, "base64");
               let decodedCredentials = buffer.toString("utf8"); //Format is like: {username}:{password}
      
               //Get single credentials
               let credentialsArray : Array<string> = decodedCredentials.split(":");
               let userName : string = credentialsArray[0];
               let userPassword : string = credentialsArray[1];
      
               if(userName && userPassword && userName === "admin" && userPassword === "secret"){
                   console.log("Authentication successful");
                   next(); //You have to call NextFunction otherwise no other middleware will do stuff
                   return;
               }
           }
      
           sendNotAuthorizedResponse(req, res);
           return;
       }
      
    3. Register after:
           app.use(customAuth);
      

    Snapshot 4: SOAP Service Including Auth Ready

    About Us Contact Imprint Terms Data privacy
    © 2024 DocuWare Corporation powered by DocFX Back to top