@volcanicminds/tools 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/main.d.ts +2 -0
- package/dist/lib/main.d.ts.map +1 -0
- package/dist/lib/main.js +4 -0
- package/dist/lib/main.js.map +1 -0
- package/dist/lib/mfa/index.d.ts +10 -0
- package/dist/lib/mfa/index.d.ts.map +1 -0
- package/dist/lib/mfa/index.js +47 -0
- package/dist/lib/mfa/index.js.map +1 -0
- package/dist/lib/util/logger.d.ts +7 -0
- package/dist/lib/util/logger.d.ts.map +1 -0
- package/dist/lib/util/logger.js +19 -0
- package/dist/lib/util/logger.js.map +1 -0
- package/lib/main.ts +3 -0
- package/lib/mfa/index.ts +89 -0
- package/lib/util/logger.ts +23 -0
- package/package.json +95 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Volcanic Minds
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[](https://opensource.org/licenses/MIT)
|
|
2
|
+
[](https://en.wikipedia.org/wiki/Open_source)
|
|
3
|
+
[](https://github.com/volcanicminds/volcanic-typeorm)
|
|
4
|
+
[](https://www.npmjs.com/package/@volcanicminds/tools)
|
|
5
|
+
|
|
6
|
+
# volcanic-tools
|
|
7
|
+
|
|
8
|
+
Tools for the volcanic (minds) backend. This library provides a collection of modular utilities designed to be tree-shakeable.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @volcanicminds/tools
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How to upgrade packages
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run upgrade-deps
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Environment
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# or automatically use LOG_LEVEL
|
|
26
|
+
SOME_KEY=true
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
This package supports both root imports and sub-path imports to optimize bundle size.
|
|
32
|
+
|
|
33
|
+
### Import everything
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { mfa, log } from '@volcanicminds/tools'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Import specific features (Recommended for smaller bundles)
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import * as mfa from '@volcanicminds/tools/mfa'
|
|
43
|
+
import * as logger from '@volcanicminds/tools/logger'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
### MFA (Multi-Factor Authentication)
|
|
49
|
+
|
|
50
|
+
Utilities for generating secrets, QR codes, and verifying TOTP tokens.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import * as mfa from '@volcanicminds/tools/mfa'
|
|
54
|
+
|
|
55
|
+
// Generate Setup
|
|
56
|
+
const { secret, uri, qrCode } = await mfa.generateSetupDetails('MyApp', 'user@example.com')
|
|
57
|
+
|
|
58
|
+
// Verify Token
|
|
59
|
+
const isValid = mfa.verifyToken('123456', secret)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Logging
|
|
63
|
+
|
|
64
|
+
Use Pino logger if in your project you have a `global.log` with a valid instance.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAA;AACzC,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAA;AACzC,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../lib/main.ts"],"names":[],"mappings":"AAAA,wBAAgB,IAAI,SAEnB"}
|
package/dist/lib/main.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../lib/main.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;AACxC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface MfaSetupDetails {
|
|
2
|
+
secret: string;
|
|
3
|
+
uri: string;
|
|
4
|
+
qrCode: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function generateSecret(size?: number): string;
|
|
7
|
+
export declare function generateSetupDetails(appName: string, username: string, secret?: string): Promise<MfaSetupDetails>;
|
|
8
|
+
export declare function verifyToken(token: string, secret: string, window?: number): boolean;
|
|
9
|
+
export declare function generateToken(secret: string): string;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/mfa/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf;AAOD,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAW,GAAG,MAAM,CAGxD;AAQD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CAqB1B;AASD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,OAAO,CAatF;AAOD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASpD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as OTPAuth from 'otpauth';
|
|
2
|
+
import QRCode from 'qrcode';
|
|
3
|
+
export function generateSecret(size = 20) {
|
|
4
|
+
const secret = new OTPAuth.Secret({ size });
|
|
5
|
+
return secret.base32;
|
|
6
|
+
}
|
|
7
|
+
export async function generateSetupDetails(appName, username, secret) {
|
|
8
|
+
const mfaSecret = secret ? OTPAuth.Secret.fromBase32(secret) : new OTPAuth.Secret({ size: 20 });
|
|
9
|
+
const base32Secret = mfaSecret.base32;
|
|
10
|
+
const totp = new OTPAuth.TOTP({
|
|
11
|
+
issuer: appName,
|
|
12
|
+
label: username,
|
|
13
|
+
algorithm: 'SHA1',
|
|
14
|
+
digits: 6,
|
|
15
|
+
period: 30,
|
|
16
|
+
secret: mfaSecret
|
|
17
|
+
});
|
|
18
|
+
const uri = totp.toString();
|
|
19
|
+
const qrCode = await QRCode.toDataURL(uri);
|
|
20
|
+
return {
|
|
21
|
+
secret: base32Secret,
|
|
22
|
+
uri,
|
|
23
|
+
qrCode
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function verifyToken(token, secret, window = 1) {
|
|
27
|
+
if (!token || !secret)
|
|
28
|
+
return false;
|
|
29
|
+
const totp = new OTPAuth.TOTP({
|
|
30
|
+
algorithm: 'SHA1',
|
|
31
|
+
digits: 6,
|
|
32
|
+
period: 30,
|
|
33
|
+
secret: OTPAuth.Secret.fromBase32(secret)
|
|
34
|
+
});
|
|
35
|
+
const delta = totp.validate({ token, window });
|
|
36
|
+
return delta !== null;
|
|
37
|
+
}
|
|
38
|
+
export function generateToken(secret) {
|
|
39
|
+
const totp = new OTPAuth.TOTP({
|
|
40
|
+
algorithm: 'SHA1',
|
|
41
|
+
digits: 6,
|
|
42
|
+
period: 30,
|
|
43
|
+
secret: OTPAuth.Secret.fromBase32(secret)
|
|
44
|
+
});
|
|
45
|
+
return totp.generate();
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/mfa/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,MAAM,MAAM,QAAQ,CAAA;AAa3B,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE;IAC9C,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3C,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAe,EACf,QAAgB,EAChB,MAAe;IAEf,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IAC/F,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAA;IAErC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;QAC5B,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,MAAM;QACjB,MAAM,EAAE,CAAC;QACT,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,SAAS;KAClB,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAE1C,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,GAAG;QACH,MAAM;KACP,CAAA;AACH,CAAC;AASD,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,MAAc,EAAE,SAAiB,CAAC;IAC3E,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEnC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;QAC5B,SAAS,EAAE,MAAM;QACjB,MAAM,EAAE,CAAC;QACT,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;KAC1C,CAAC,CAAA;IAGF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IAC9C,OAAO,KAAK,KAAK,IAAI,CAAA;AACvB,CAAC;AAOD,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;QAC5B,SAAS,EAAE,MAAM;QACjB,MAAM,EAAE,CAAC;QACT,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;KAC1C,CAAC,CAAA;IAEF,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function trace(data: any): void;
|
|
2
|
+
export declare function debug(data: any): void;
|
|
3
|
+
export declare function info(data: any): void;
|
|
4
|
+
export declare function warn(data: any): void;
|
|
5
|
+
export declare function error(data: any): void;
|
|
6
|
+
export declare function fatal(data: any): void;
|
|
7
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../lib/util/logger.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,CAAC,IAAI,KAAA,QAEzB;AAED,wBAAgB,KAAK,CAAC,IAAI,KAAA,QAEzB;AAED,wBAAgB,IAAI,CAAC,IAAI,KAAA,QAExB;AAED,wBAAgB,IAAI,CAAC,IAAI,KAAA,QAExB;AAED,wBAAgB,KAAK,CAAC,IAAI,KAAA,QAEzB;AAED,wBAAgB,KAAK,CAAC,IAAI,KAAA,QAEzB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function trace(data) {
|
|
2
|
+
global.isLoggingEnabled && global.log?.trace && global.log.trace(data);
|
|
3
|
+
}
|
|
4
|
+
export function debug(data) {
|
|
5
|
+
global.isLoggingEnabled && global.log?.debug && global.log.debug(data);
|
|
6
|
+
}
|
|
7
|
+
export function info(data) {
|
|
8
|
+
global.isLoggingEnabled && global.log?.info && global.log.info(data);
|
|
9
|
+
}
|
|
10
|
+
export function warn(data) {
|
|
11
|
+
global.isLoggingEnabled && global.log?.warn && global.log.warn(data);
|
|
12
|
+
}
|
|
13
|
+
export function error(data) {
|
|
14
|
+
global.isLoggingEnabled && global.log?.error && global.log.error(data);
|
|
15
|
+
}
|
|
16
|
+
export function fatal(data) {
|
|
17
|
+
global.isLoggingEnabled && global.log?.fatal && global.log.fatal(data);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../lib/util/logger.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,KAAK,CAAC,IAAI;IACxB,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AACxE,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAI;IACxB,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AACxE,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAI;IACvB,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,GAAG,EAAE,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAI;IACvB,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,GAAG,EAAE,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAI;IACxB,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AACxE,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAI;IACxB,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AACxE,CAAC"}
|
package/lib/main.ts
ADDED
package/lib/mfa/index.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as OTPAuth from 'otpauth'
|
|
2
|
+
import QRCode from 'qrcode'
|
|
3
|
+
|
|
4
|
+
export interface MfaSetupDetails {
|
|
5
|
+
secret: string
|
|
6
|
+
uri: string
|
|
7
|
+
qrCode: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generates a new random base32 secret.
|
|
12
|
+
* @param size The size of the secret in bytes (default 20).
|
|
13
|
+
* @returns The base32 string representation of the secret.
|
|
14
|
+
*/
|
|
15
|
+
export function generateSecret(size: number = 20): string {
|
|
16
|
+
const secret = new OTPAuth.Secret({ size })
|
|
17
|
+
return secret.base32
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Generates setup details for the client, including the secret, the otpauth URI, and a QR code Data URL.
|
|
22
|
+
* @param appName The name of the application (Issuer).
|
|
23
|
+
* @param username The username (Label).
|
|
24
|
+
* @param secret The base32 secret (optional, will be generated if not provided).
|
|
25
|
+
*/
|
|
26
|
+
export async function generateSetupDetails(
|
|
27
|
+
appName: string,
|
|
28
|
+
username: string,
|
|
29
|
+
secret?: string
|
|
30
|
+
): Promise<MfaSetupDetails> {
|
|
31
|
+
const mfaSecret = secret ? OTPAuth.Secret.fromBase32(secret) : new OTPAuth.Secret({ size: 20 })
|
|
32
|
+
const base32Secret = mfaSecret.base32
|
|
33
|
+
|
|
34
|
+
const totp = new OTPAuth.TOTP({
|
|
35
|
+
issuer: appName,
|
|
36
|
+
label: username,
|
|
37
|
+
algorithm: 'SHA1',
|
|
38
|
+
digits: 6,
|
|
39
|
+
period: 30,
|
|
40
|
+
secret: mfaSecret
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const uri = totp.toString()
|
|
44
|
+
const qrCode = await QRCode.toDataURL(uri)
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
secret: base32Secret,
|
|
48
|
+
uri,
|
|
49
|
+
qrCode
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Validates a TOTP token against a secret.
|
|
55
|
+
* @param token The token to verify.
|
|
56
|
+
* @param secret The base32 secret.
|
|
57
|
+
* @param window The acceptable time window (default 1, meaning +/- 30 seconds).
|
|
58
|
+
* @returns True if valid, false otherwise.
|
|
59
|
+
*/
|
|
60
|
+
export function verifyToken(token: string, secret: string, window: number = 1): boolean {
|
|
61
|
+
if (!token || !secret) return false
|
|
62
|
+
|
|
63
|
+
const totp = new OTPAuth.TOTP({
|
|
64
|
+
algorithm: 'SHA1',
|
|
65
|
+
digits: 6,
|
|
66
|
+
period: 30,
|
|
67
|
+
secret: OTPAuth.Secret.fromBase32(secret)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// validate returns null if invalid, or the delta (integer) if valid
|
|
71
|
+
const delta = totp.validate({ token, window })
|
|
72
|
+
return delta !== null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Generates the current TOTP token for a given secret.
|
|
77
|
+
* Useful for testing or recovery scenarios.
|
|
78
|
+
* @param secret The base32 secret.
|
|
79
|
+
*/
|
|
80
|
+
export function generateToken(secret: string): string {
|
|
81
|
+
const totp = new OTPAuth.TOTP({
|
|
82
|
+
algorithm: 'SHA1',
|
|
83
|
+
digits: 6,
|
|
84
|
+
period: 30,
|
|
85
|
+
secret: OTPAuth.Secret.fromBase32(secret)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return totp.generate()
|
|
89
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function trace(data) {
|
|
2
|
+
global.isLoggingEnabled && global.log?.trace && global.log.trace(data)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function debug(data) {
|
|
6
|
+
global.isLoggingEnabled && global.log?.debug && global.log.debug(data)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function info(data) {
|
|
10
|
+
global.isLoggingEnabled && global.log?.info && global.log.info(data)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function warn(data) {
|
|
14
|
+
global.isLoggingEnabled && global.log?.warn && global.log.warn(data)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function error(data) {
|
|
18
|
+
global.isLoggingEnabled && global.log?.error && global.log.error(data)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function fatal(data) {
|
|
22
|
+
global.isLoggingEnabled && global.log?.fatal && global.log.fatal(data)
|
|
23
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@volcanicminds/tools",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Tools for the volcanic (minds) backend",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"volcanic",
|
|
7
|
+
"open source",
|
|
8
|
+
"tools",
|
|
9
|
+
"typescript",
|
|
10
|
+
"esm",
|
|
11
|
+
"mfa",
|
|
12
|
+
"otp",
|
|
13
|
+
"totp"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://volcanicminds.com",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/volcanicminds/volcanic-tools/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/volcanicminds/volcanic-tools.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "Volcanic Minds <developers@volcanicminds.com> (https://volcanicminds.com)",
|
|
25
|
+
"maintainers": [
|
|
26
|
+
{
|
|
27
|
+
"name": "Developers",
|
|
28
|
+
"email": "developers@volcanicminds.com",
|
|
29
|
+
"url": "https://volcanicminds.com"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"type": "module",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js",
|
|
37
|
+
"require": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./mfa": {
|
|
40
|
+
"types": "./dist/lib/mfa/index.d.ts",
|
|
41
|
+
"import": "./dist/lib/mfa/index.js",
|
|
42
|
+
"require": "./dist/lib/mfa/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./logger": {
|
|
45
|
+
"types": "./dist/lib/util/logger.d.ts",
|
|
46
|
+
"import": "./dist/lib/util/logger.js",
|
|
47
|
+
"require": "./dist/lib/util/logger.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"main": "dist/index.js",
|
|
51
|
+
"types": "dist/index.d.ts",
|
|
52
|
+
"directories": {
|
|
53
|
+
"lib": "lib"
|
|
54
|
+
},
|
|
55
|
+
"files": [
|
|
56
|
+
"dist",
|
|
57
|
+
"lib"
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"clean": "rm -rf dist",
|
|
61
|
+
"prebuild": "npm run clean",
|
|
62
|
+
"build": "tsc",
|
|
63
|
+
"reset": "npm install && npm update && npm run build",
|
|
64
|
+
"upgrade-deps": "npx npm-check-updates -u",
|
|
65
|
+
"combine": "node combine.js"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"otpauth": "^9.3.5",
|
|
69
|
+
"qrcode": "^1.5.4"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@types/node": "^24.10.1",
|
|
73
|
+
"@types/qrcode": "^1.5.5",
|
|
74
|
+
"tsx": "^4.19.2",
|
|
75
|
+
"typescript": "^5.9.3"
|
|
76
|
+
},
|
|
77
|
+
"engines": {
|
|
78
|
+
"node": ">=24"
|
|
79
|
+
},
|
|
80
|
+
"module": "dist/index.js",
|
|
81
|
+
"sideEffects": false,
|
|
82
|
+
"typesVersions": {
|
|
83
|
+
"*": {
|
|
84
|
+
"*": [
|
|
85
|
+
"dist/index.d.ts"
|
|
86
|
+
],
|
|
87
|
+
"mfa": [
|
|
88
|
+
"dist/lib/mfa/index.d.ts"
|
|
89
|
+
],
|
|
90
|
+
"logger": [
|
|
91
|
+
"dist/lib/util/logger.d.ts"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|