Skip to content

Commit

Permalink
feat: add sid method
Browse files Browse the repository at this point in the history
  • Loading branch information
jooy2 committed May 3, 2024
1 parent 6fc87ae commit ca36a2d
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## 1.0.2 (2024-05-)

- feat: add `sid` method

## 1.0.1 (2024-04-03)

- `machineId`: Fix bug on Windows
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ This method returns the same value for every user on the system.
console.log(await machineId()); // a642d9e1-6063-4da7-8ea8-2298f989d01d
```

### `sid (Promise<string>)`

Gets the Secutify Identifier (SID) value for the current user on the device. Throws an error if the value is not obtained.

The SID value is only supported on Windows and macOS. Other OSes throw an error.

Also, the SID value used on macOS is a value created for the directory service. If you don't trust this value, use the `machineId` method instead.

This value can be changed by the user.

```javascript
console.log(await sid()); // S-1-5-21-406418252-5582013529-1321253100-2001
```

## Contribute

You can report issues on [GitHub Issue Tracker](https://github.com/jooy2/machini/issues). You can also request a pull to fix bugs and add frequently used features.
Expand Down
74 changes: 72 additions & 2 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { platform } from 'os';
import { platform, homedir, userInfo } from 'os';
import { exec as processExec } from 'child_process';

declare type AnyValueObject = { [key: string]: any };

const execCommand = (platformName: string, command: string): Promise<string> =>
new Promise((resolve, reject) => {
const execCommandProcess = processExec(
Expand Down Expand Up @@ -53,8 +55,76 @@ export default class Machini {

throw new Error('Failed to get machine id');
}

static async sid(): Promise<string> {
const platformName = platform();

if (platformName === 'win32') {
try {
const profileLists = await execCommand(
platformName,
`REG QUERY "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList" /s`
);

const profiles: AnyValueObject = {};
const sections = profileLists.split('HKEY_LOCAL_MACHINE\\');

sections.forEach((section) => {
const lines = section
.split('\n')
.map((line) => line.trim())
.filter((line) => line);

if (lines.length > 0) {
const keyName: string = lines[0].split('\\').pop() || 'Unknown';
const profileImagePath = lines.find((line) => line.startsWith('ProfileImagePath'));

if (profileImagePath) {
profiles[keyName] = profileImagePath.split(' ').pop() || 'Unknown';
}
}
});

for (let i = 0; i < Object.keys(profiles).length; i += 1) {
const key = Object.keys(profiles)[i];
const value = profiles[key];

if (value === homedir()) {
return key;
}
}
} catch (error) {
if (error instanceof Error) {
throw new Error(error?.message);
}
}

throw new Error('Failed to get machine id');
}

if (platformName === 'darwin') {
try {
const execResult = await execCommand(
platformName,
`dsmemberutil getsid -U ${userInfo().username}`
);

if (execResult) {
return execResult.replace(/\r?\n/g, '');
}
} catch (error) {
if (error instanceof Error) {
throw new Error(error?.message);
}
}

throw new Error('Failed to get machine id');
}

throw new Error('Not supported on this operating system.');
}
}

export { Machini };

export const { machineId } = Machini;
export const { machineId, sid } = Machini;
29 changes: 21 additions & 8 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import assert from 'assert';
import { machineId } from '../dist';

/*
* Sample Response:
* Windows: a642d9e1-6063-4da7-8ea8-2298f989d01d
* Linux: 5c6ee51d3e514eb4883e4373e320192c
* macOS: BAC04154-124A-56E1-BFEB-D6D94FE5DBC0
*/
import { machineId, sid } from '../dist';

describe('Module Test', () => {
/*
* Sample Response:
* Windows: a642d9e1-6063-4da7-8ea8-2298f989d01d
* Linux: 5c6ee51d3e514eb4883e4373e320192c
* macOS: BAC04154-124A-56E1-BFEB-D6D94FE5DBC0
*/
it('machineId', async () => {
const mId = await machineId();

Expand All @@ -26,4 +26,17 @@ describe('Module Test', () => {

assert.match(mId, regex);
});

// Example: S-1-5-21-406418252-5582013529-1321253100-2001
it('sid', async () => {
const { platform } = process;

if (platform !== 'win32' && platform !== 'darwin') {
return;
}

const sidResult = await sid();

assert.match(sidResult, /^S-1-[0-59]-\d{2}-\d{8,10}-\d{8,10}-\d{8,10}-[1-9]\d{3}/);
});
});

0 comments on commit ca36a2d

Please sign in to comment.