index.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* @flow */
  2. import {exec, execSync} from 'child_process';
  3. import {createHash} from 'crypto';
  4. let {platform}: Object = process,
  5. win32RegBinPath = {
  6. native: '%windir%\\System32',
  7. mixed: '%windir%\\sysnative\\cmd.exe /c %windir%\\System32'
  8. },
  9. guid: Object = {
  10. darwin: 'ioreg -rd1 -c IOPlatformExpertDevice',
  11. win32: `${win32RegBinPath[isWindowsProcessMixedOrNativeArchitecture()]}\\REG.exe ` +
  12. 'QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography ' +
  13. '/v MachineGuid',
  14. linux: '( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :',
  15. freebsd: 'kenv -q smbios.system.uuid || sysctl -n kern.hostuuid'
  16. };
  17. function isWindowsProcessMixedOrNativeArchitecture(): string {
  18. // detect if the node binary is the same arch as the Windows OS.
  19. // or if this is 32 bit node on 64 bit windows.
  20. if(process.platform !== 'win32') {
  21. return '';
  22. }
  23. if( process.arch === 'ia32' && process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432') ) {
  24. return 'mixed';
  25. }
  26. return 'native';
  27. }
  28. function hash(guid: string): string {
  29. return createHash('sha256').update(guid).digest('hex');
  30. }
  31. function expose(result: string): string {
  32. switch (platform) {
  33. case 'darwin':
  34. return result
  35. .split('IOPlatformUUID')[1]
  36. .split('\n')[0].replace(/\=|\s+|\"/ig, '')
  37. .toLowerCase();
  38. case 'win32':
  39. return result
  40. .toString()
  41. .split('REG_SZ')[1]
  42. .replace(/\r+|\n+|\s+/ig, '')
  43. .toLowerCase();
  44. case 'linux':
  45. return result
  46. .toString()
  47. .replace(/\r+|\n+|\s+/ig, '')
  48. .toLowerCase();
  49. case 'freebsd':
  50. return result
  51. .toString()
  52. .replace(/\r+|\n+|\s+/ig, '')
  53. .toLowerCase();
  54. default:
  55. throw new Error(`Unsupported platform: ${process.platform}`);
  56. }
  57. }
  58. export function machineIdSync(original: boolean): string {
  59. let id: string = expose(execSync(guid[platform]).toString());
  60. return original ? id : hash(id);
  61. }
  62. export function machineId(original: boolean): Promise<string> {
  63. return new Promise((resolve: Function, reject: Function): Object => {
  64. return exec(guid[platform], {}, (err: any, stdout: any, stderr: any) => {
  65. if (err) {
  66. return reject(
  67. new Error(`Error while obtaining machine id: ${err.stack}`)
  68. );
  69. }
  70. let id: string = expose(stdout.toString());
  71. return resolve(original ? id : hash(id));
  72. });
  73. });
  74. }