Angular Issue in production build, but not in local development. ERROR TypeError: Cannot read property 'call' of undefined

Viewed 1758

I've been having an issue where one of my Angular 8 apps works without issues and as expected when ran locally (ng serve), however, when built and ran on production (ng build) it will give me the below error when a component is clicked in my app and code is ran.

Error received in console:

ERROR TypeError: Cannot read property 'call' of undefined
    at d.l (main-es2015.5d76d03ab70e1112760a.js:1)
    at new d (main-es2015.5d76d03ab70e1112760a.js:1)
    at Giow.e.exports (main-es2015.5d76d03ab70e1112760a.js:1)
    at e.df (main-es2015.5d76d03ab70e1112760a.js:1)
    at e.stretch (main-es2015.5d76d03ab70e1112760a.js:1)
    at e.getHashPassword (main-es2015.5d76d03ab70e1112760a.js:1)
    at p.newAccount (main-es2015.5d76d03ab70e1112760a.js:1)
    at Object.handleEvent (main-es2015.5d76d03ab70e1112760a.js:1)
    at Object.handleEvent (main-es2015.5d76d03ab70e1112760a.js:1)
    at Object.handleEvent (main-es2015.5d76d03ab70e1112760a.js:1)
br @ main-es2015.5d76d03ab70e1112760a.js:1
handleError @ main-es2015.5d76d03ab70e1112760a.js:1
Xp @ main-es2015.5d76d03ab70e1112760a.js:1
(anonymous) @ main-es2015.5d76d03ab70e1112760a.js:1
(anonymous) @ main-es2015.5d76d03ab70e1112760a.js:1
invokeTask @ polyfills-es2015.a8cec314c5933902d1c0.js:1
onInvokeTask @ main-es2015.5d76d03ab70e1112760a.js:1
invokeTask @ polyfills-es2015.a8cec314c5933902d1c0.js:1
runTask @ polyfills-es2015.a8cec314c5933902d1c0.js:1
invokeTask @ polyfills-es2015.a8cec314c5933902d1c0.js:1
y @ polyfills-es2015.a8cec314c5933902d1c0.js:1
b @ polyfills-es2015.a8cec314c5933902d1c0.js:1

Error after disabling minification using below stackblitz example:

ERROR TypeError: Cannot read property 'call' of undefined
    at Hmac.CipherBase (main-es2015.02649c002b843ca5ea1e.js:63726)
    at new Hmac (main-es2015.02649c002b843ca5ea1e.js:63860)
    at createHmac (main-es2015.02649c002b843ca5ea1e.js:63907)
    at PasswordService.uno_hkdf (main-es2015.02649c002b843ca5ea1e.js:77684)
    at PasswordService.stretch (main-es2015.02649c002b843ca5ea1e.js:77671)
    at AppComponent.ngOnInit (main-es2015.02649c002b843ca5ea1e.js:77535)
    at checkAndUpdateDirectiveInline (main-es2015.02649c002b843ca5ea1e.js:36518)
    at checkAndUpdateNodeInline (main-es2015.02649c002b843ca5ea1e.js:47852)
    at checkAndUpdateNode (main-es2015.02649c002b843ca5ea1e.js:47791)
    at prodCheckAndUpdateNode (main-es2015.02649c002b843ca5ea1e.js:48645)

Code:

import { Injectable } from '@angular/core';
import { pbkdf2Sync } from 'pbkdf2';
import * as createHmac from 'create-hmac';

@Injectable()
export class PasswordService {
  public stretch(emailInput, passwordInput) {
    const salt = new Buffer('identity.mozilla.com/picl/v1/' + 'quickStretch' + ':' + emailInput, 'utf8');
    const password = new Buffer(passwordInput, 'utf8');
    const key: Buffer = pbkdf2Sync(password, salt, 1000, 128, 'sha256');
    const info = new Buffer('identity.mozilla.com/picl/v1/' + 'authPW', 'utf8');
    const outcome = this.df(key, info, '', 128);
    return outcome;
  }

  df(key, info, salt, length) {
    const k = createHmac('sha256', salt).update(key).digest(); /* <----------- FAILS HERE */
    const k2 = createHmac('sha256', k);
    const counter = new Buffer([1]);
    k2.update(info);
    k2.update(counter);
    return k2.digest().toString('base64');
  }
}

After debugging and stepping through the service via developer console, I found that it will fail on the first line of my df function, specifically at createHmac('sha256', salt); It seems like the create-hmac package is undefined, but I'm not sure why it would compile without errors in this case. I have been unable to find any similar issues related to the 'create-hmac' package online which leads me to believe it has something to do with how my app is setup but I'm not sure where to start looking.

Things I have tried from various searches online but always resulted in the same error:

1. rm -rf /node_modules/ -> npm update -> npm install
2. require() instead of import()
3. es5 to es2015 in tsconfig.json
4. Updating create-hmac and pbkdf2 packages
5. Downgrading @angular/cli and @angular-devkit/build-angular
6. Build with other flags such as ```ng build --build-optimizer --aot```
7. Node v10.15, v10.16, and v12.16
8. Using a constructor for createHmac
9. Using import createHmac from 'create-hmac'

ng --version

Angular CLI: 8.3.20
Node: 10.16.0
OS: linux x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.20
@angular-devkit/build-angular     0.803.20
@angular-devkit/build-optimizer   0.803.20
@angular-devkit/build-webpack     0.803.20
@angular-devkit/core              8.3.20
@angular-devkit/schematics        8.3.20
@angular/cdk                      8.2.3
@angular/cli                      8.3.20
@angular/http                     7.2.16
@angular/material                 8.2.3
@ngtools/webpack                  8.3.20
@schematics/angular               8.3.20
@schematics/update                0.803.20
rxjs                              6.5.4
typescript                        3.5.3
webpack                           4.39.2

Any insight is appreciated. Thanks!

SOLUTION FOUND https://forum.aeternity.com/t/important-fix-for-angular-typeerror-cannot-read-property-call-of-undefined-at-hash-cipherbase-index-js-7/4153

1 Answers

Look at this stackblitz I created (with angular 8 as per your setup):

https://stackblitz.com/edit/so-60536842-create-hmac

The one change I had to do to make it work as regards your code is:

import createHmac from 'create-hmac';

Otherwise (import * as createHmac from 'create-hmac';) was throwing me an error: createHmac is not a function

Related