namirasoft-node 1.0.9 → 1.0.12
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/dist/OTPOperation.d.ts +12 -0
- package/dist/OTPOperation.js +70 -0
- package/dist/OTPOperation.js.map +1 -0
- package/package.json +1 -1
- package/public/index.html +2 -0
- package/src/OTPOperation.ts +65 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class OTPOperation {
|
|
2
|
+
static generate(length?: number, digit?: number): string;
|
|
3
|
+
static getWaitTime(min_wait_time: number, max_wait_time: number, min_attempt: number, user_attemptted: number, increase_power_base?: number): number;
|
|
4
|
+
static onSafeRequest(handler: () => Promise<void>, last_tried_time: Date, min_wait_time: number, max_wait_time: number, min_attempt: number, user_attemptted: number, increase_power_base?: number): Promise<{
|
|
5
|
+
error: string;
|
|
6
|
+
next_time: number;
|
|
7
|
+
} | {
|
|
8
|
+
next_time: number;
|
|
9
|
+
error?: undefined;
|
|
10
|
+
}>;
|
|
11
|
+
static onSafeVerify(otp: string, otp_expire_time: number, max_try_count: number, user_otp: string, user_otp_time: Date, user_tried_count: number, handler: () => Promise<void>, errorHandler: () => Promise<void>): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.OTPOperation = void 0;
|
|
13
|
+
const namirasoft_core_1 = require("namirasoft-core");
|
|
14
|
+
class OTPOperation {
|
|
15
|
+
static generate(length = 6, digit = 3) {
|
|
16
|
+
if (!length)
|
|
17
|
+
length = 6;
|
|
18
|
+
if (!digit)
|
|
19
|
+
digit = 3;
|
|
20
|
+
let dig = [];
|
|
21
|
+
for (let i = 0; i < digit; i++)
|
|
22
|
+
dig[i] = parseInt((Math.random() * 9 + 1) + "");
|
|
23
|
+
let ans = '';
|
|
24
|
+
for (let i = 0; i < length; i++)
|
|
25
|
+
ans = ans + '' + dig[parseInt((Math.random() * dig.length) + "")];
|
|
26
|
+
return ans;
|
|
27
|
+
}
|
|
28
|
+
static getWaitTime(min_wait_time, max_wait_time, min_attempt, user_attemptted, increase_power_base = 2) {
|
|
29
|
+
let wait_time = min_wait_time;
|
|
30
|
+
let extra_attempt = user_attemptted - min_attempt;
|
|
31
|
+
if (extra_attempt > 0)
|
|
32
|
+
wait_time = Math.min(Math.pow(increase_power_base, extra_attempt) * 60, max_wait_time);
|
|
33
|
+
return parseInt(wait_time + "");
|
|
34
|
+
}
|
|
35
|
+
static onSafeRequest(handler, last_tried_time, min_wait_time, max_wait_time, min_attempt, user_attemptted, increase_power_base = 2) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
// check wait time
|
|
38
|
+
let wait_time = this.getWaitTime(min_wait_time, max_wait_time, min_attempt, user_attemptted, increase_power_base);
|
|
39
|
+
let wait_date = namirasoft_core_1.TimeOperation.minutesAgo(wait_time, new Date());
|
|
40
|
+
let next_time = namirasoft_core_1.TimeOperation.diffInSecond(last_tried_time, wait_date, false);
|
|
41
|
+
if (next_time > 0) {
|
|
42
|
+
return {
|
|
43
|
+
error: 'Too many request, please try again in ' + next_time + ' seconds.',
|
|
44
|
+
next_time
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
yield handler();
|
|
48
|
+
wait_time = this.getWaitTime(min_wait_time, max_wait_time, min_attempt, user_attemptted + 1, increase_power_base);
|
|
49
|
+
next_time = wait_time * 60;
|
|
50
|
+
return { next_time };
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
static onSafeVerify(otp, otp_expire_time, max_try_count, user_otp, user_otp_time, user_tried_count, handler, errorHandler) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
if (!otp)
|
|
56
|
+
namirasoft_core_1.ErrorOperation.throwHTTP(403, "The OTP not generated yet.");
|
|
57
|
+
if (user_otp_time < namirasoft_core_1.TimeOperation.minutesAgo(otp_expire_time, new Date()))
|
|
58
|
+
namirasoft_core_1.ErrorOperation.throwHTTP(403, "The OTP code expired. Please request again.");
|
|
59
|
+
if (user_tried_count > max_try_count)
|
|
60
|
+
namirasoft_core_1.ErrorOperation.throwHTTP(403, "The try limit attempt exceeded. Please request again.");
|
|
61
|
+
if (user_otp !== otp) {
|
|
62
|
+
yield errorHandler();
|
|
63
|
+
namirasoft_core_1.ErrorOperation.throwHTTP(403, "Wrong code.");
|
|
64
|
+
}
|
|
65
|
+
yield handler();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.OTPOperation = OTPOperation;
|
|
70
|
+
//# sourceMappingURL=OTPOperation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OTPOperation.js","sourceRoot":"","sources":["../src/OTPOperation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
<title>@title</title>
|
|
8
8
|
<!-- Include Bootstrap CSS -->
|
|
9
9
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
|
10
|
+
<link rel="icon" type="image/x-icon" href="@logo">
|
|
11
|
+
<meta property="og:image" content="@logo">
|
|
10
12
|
<style>
|
|
11
13
|
body {
|
|
12
14
|
background-color: #f8f9fa;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ErrorOperation, TimeOperation } from "namirasoft-core";
|
|
2
|
+
|
|
3
|
+
export class OTPOperation
|
|
4
|
+
{
|
|
5
|
+
static generate(length: number = 6, digit: number = 3)
|
|
6
|
+
{
|
|
7
|
+
if (!length)
|
|
8
|
+
length = 6;
|
|
9
|
+
if (!digit)
|
|
10
|
+
digit = 3;
|
|
11
|
+
let dig = [];
|
|
12
|
+
for (let i = 0; i < digit; i++)
|
|
13
|
+
dig[i] = parseInt((Math.random() * 9 + 1) + "");
|
|
14
|
+
let ans = '';
|
|
15
|
+
for (let i = 0; i < length; i++)
|
|
16
|
+
ans = ans + '' + dig[parseInt((Math.random() * dig.length) + "")];
|
|
17
|
+
return ans;
|
|
18
|
+
}
|
|
19
|
+
static getWaitTime(min_wait_time: number, max_wait_time: number, min_attempt: number, user_attemptted: number, increase_power_base: number = 2): number
|
|
20
|
+
{
|
|
21
|
+
let wait_time = min_wait_time;
|
|
22
|
+
let extra_attempt = user_attemptted - min_attempt;
|
|
23
|
+
if (extra_attempt > 0)
|
|
24
|
+
wait_time = Math.min(Math.pow(increase_power_base, extra_attempt) * 60, max_wait_time);
|
|
25
|
+
return parseInt(wait_time + "");
|
|
26
|
+
}
|
|
27
|
+
static async onSafeRequest(handler: () => Promise<void>, last_tried_time: Date, min_wait_time: number, max_wait_time: number, min_attempt: number, user_attemptted: number, increase_power_base: number = 2)
|
|
28
|
+
{
|
|
29
|
+
// check wait time
|
|
30
|
+
let wait_time = this.getWaitTime(min_wait_time, max_wait_time, min_attempt, user_attemptted, increase_power_base);
|
|
31
|
+
let wait_date = TimeOperation.minutesAgo(wait_time, new Date());
|
|
32
|
+
let next_time = TimeOperation.diffInSecond(last_tried_time, wait_date, false);
|
|
33
|
+
if (next_time > 0)
|
|
34
|
+
{
|
|
35
|
+
return {
|
|
36
|
+
error: 'Too many request, please try again in ' + next_time + ' seconds.',
|
|
37
|
+
next_time
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
await handler();
|
|
41
|
+
wait_time = this.getWaitTime(min_wait_time, max_wait_time, min_attempt, user_attemptted + 1, increase_power_base);
|
|
42
|
+
next_time = wait_time * 60;
|
|
43
|
+
return { next_time };
|
|
44
|
+
}
|
|
45
|
+
static async onSafeVerify(otp: string, otp_expire_time: number, max_try_count: number,
|
|
46
|
+
user_otp: string, user_otp_time: Date, user_tried_count: number,
|
|
47
|
+
handler: () => Promise<void>, errorHandler: () => Promise<void>)
|
|
48
|
+
{
|
|
49
|
+
if (!otp)
|
|
50
|
+
ErrorOperation.throwHTTP(403, "The OTP not generated yet.");
|
|
51
|
+
|
|
52
|
+
if (user_otp_time < TimeOperation.minutesAgo(otp_expire_time, new Date()))
|
|
53
|
+
ErrorOperation.throwHTTP(403, "The OTP code expired. Please request again.");
|
|
54
|
+
|
|
55
|
+
if (user_tried_count > max_try_count)
|
|
56
|
+
ErrorOperation.throwHTTP(403, "The try limit attempt exceeded. Please request again.");
|
|
57
|
+
|
|
58
|
+
if (user_otp !== otp)
|
|
59
|
+
{
|
|
60
|
+
await errorHandler();
|
|
61
|
+
ErrorOperation.throwHTTP(403, "Wrong code.");
|
|
62
|
+
}
|
|
63
|
+
await handler();
|
|
64
|
+
}
|
|
65
|
+
}
|