@darco2903/auth-api 2.1.4 → 2.2.0

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.
@@ -0,0 +1,81 @@
1
+ import { initContract, ZodErrorSchema } from "@ts-rest/core";
2
+ import z from "zod";
3
+ import { apiError, apiSuccess } from "../types.js";
4
+ import { authHeaderSchema, totpCodeSchema } from "../types/index.js";
5
+ const c = initContract();
6
+ export default c.router({
7
+ setup: {
8
+ method: "POST",
9
+ path: "/totp/setup",
10
+ headers: authHeaderSchema,
11
+ body: c.noBody(),
12
+ responses: {
13
+ 200: apiSuccess(z.object({
14
+ secret: z.string(),
15
+ otpauthUrl: z.string(),
16
+ })),
17
+ 400: z.union([
18
+ ZodErrorSchema,
19
+ apiError(z.literal("TOTP_ALREADY_SETUP"), z.string()),
20
+ ]),
21
+ 401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
22
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
23
+ },
24
+ },
25
+ setupConfirm: {
26
+ method: "POST",
27
+ path: "/totp/setup/confirm",
28
+ headers: authHeaderSchema,
29
+ body: z.object({
30
+ totpCode: totpCodeSchema,
31
+ }),
32
+ responses: {
33
+ 204: apiSuccess(c.noBody()),
34
+ 400: z.union([
35
+ ZodErrorSchema,
36
+ apiError(z.literal("TOTP_NOT_SETUP"), z.string()),
37
+ apiError(z.literal("TOTP_ALREADY_SETUP"), z.string()),
38
+ apiError(z.literal("TOTP_INVALID"), z.string()),
39
+ ]),
40
+ 401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
41
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
42
+ },
43
+ },
44
+ verify: {
45
+ method: "POST",
46
+ path: "/totp/verify",
47
+ headers: authHeaderSchema,
48
+ body: z.object({
49
+ totpCode: totpCodeSchema,
50
+ }),
51
+ responses: {
52
+ 204: apiSuccess(c.noBody()),
53
+ 400: z.union([
54
+ ZodErrorSchema,
55
+ apiError(z.literal("TOTP_NOT_SETUP"), z.string()),
56
+ apiError(z.literal("TOTP_NOT_REQUIRED"), z.string()),
57
+ apiError(z.literal("TOTP_INVALID"), z.string()),
58
+ ]),
59
+ 401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
60
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
61
+ },
62
+ },
63
+ disable: {
64
+ method: "POST",
65
+ path: "/totp/disable",
66
+ headers: authHeaderSchema,
67
+ body: z.object({
68
+ totpCode: totpCodeSchema,
69
+ }),
70
+ responses: {
71
+ 204: apiSuccess(c.noBody()),
72
+ 400: z.union([
73
+ ZodErrorSchema,
74
+ apiError(z.literal("TOTP_NOT_SETUP"), z.string()),
75
+ apiError(z.literal("TOTP_INVALID"), z.string()),
76
+ ]),
77
+ 401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
78
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
79
+ },
80
+ },
81
+ });
@@ -376,6 +376,7 @@ declare const _default: {
376
376
  email: z.ZodString;
377
377
  role: z.ZodNumber;
378
378
  verified: z.ZodBoolean;
379
+ totp_enabled: z.ZodBoolean;
379
380
  last_login: z.ZodNullable<z.ZodDate>;
380
381
  created_at: z.ZodDate;
381
382
  updated_at: z.ZodDate;
@@ -391,6 +392,7 @@ declare const _default: {
391
392
  };
392
393
  round_border: boolean;
393
394
  verified: boolean;
395
+ totp_enabled: boolean;
394
396
  last_login: Date | null;
395
397
  created_at: Date;
396
398
  updated_at: Date;
@@ -406,6 +408,7 @@ declare const _default: {
406
408
  };
407
409
  round_border: boolean;
408
410
  verified: boolean;
411
+ totp_enabled: boolean;
409
412
  last_login: Date | null;
410
413
  created_at: Date;
411
414
  updated_at: Date;
@@ -472,7 +475,7 @@ declare const _default: {
472
475
  authorization?: string | undefined;
473
476
  }>;
474
477
  responses: {
475
- 200: typeof import("@ts-rest/core").ContractNoBody;
478
+ 204: typeof import("@ts-rest/core").ContractNoBody;
476
479
  400: z.ZodObject<{
477
480
  name: z.ZodLiteral<"ZodError">;
478
481
  issues: z.ZodArray<z.ZodObject<{
@@ -638,7 +641,7 @@ declare const _default: {
638
641
  authorization?: string | undefined;
639
642
  }>;
640
643
  responses: {
641
- 200: typeof import("@ts-rest/core").ContractNoBody;
644
+ 204: typeof import("@ts-rest/core").ContractNoBody;
642
645
  400: z.ZodObject<{
643
646
  name: z.ZodLiteral<"ZodError">;
644
647
  issues: z.ZodArray<z.ZodObject<{
@@ -801,7 +804,7 @@ declare const _default: {
801
804
  authorization?: string | undefined;
802
805
  }>;
803
806
  responses: {
804
- 200: typeof import("@ts-rest/core").ContractNoBody;
807
+ 204: typeof import("@ts-rest/core").ContractNoBody;
805
808
  400: z.ZodObject<{
806
809
  name: z.ZodLiteral<"ZodError">;
807
810
  issues: z.ZodArray<z.ZodObject<{
@@ -964,7 +967,7 @@ declare const _default: {
964
967
  authorization?: string | undefined;
965
968
  }>;
966
969
  responses: {
967
- 200: typeof import("@ts-rest/core").ContractNoBody;
970
+ 204: typeof import("@ts-rest/core").ContractNoBody;
968
971
  400: z.ZodObject<{
969
972
  name: z.ZodLiteral<"ZodError">;
970
973
  issues: z.ZodArray<z.ZodObject<{
@@ -52,7 +52,7 @@ export default c.router({
52
52
  email: emailSchema,
53
53
  }),
54
54
  responses: {
55
- 200: apiSuccess(c.noBody()),
55
+ 204: apiSuccess(c.noBody()),
56
56
  400: ZodErrorSchema,
57
57
  401: apiError(z.literal("UNAUTHORIZED"), z.string()),
58
58
  500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
@@ -68,7 +68,7 @@ export default c.router({
68
68
  disconnectAll: z.boolean().default(true),
69
69
  }),
70
70
  responses: {
71
- 200: apiSuccess(c.noBody()),
71
+ 204: apiSuccess(c.noBody()),
72
72
  400: ZodErrorSchema,
73
73
  401: apiError(z.literal("UNAUTHORIZED"), z.string()),
74
74
  500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
@@ -83,7 +83,7 @@ export default c.router({
83
83
  username: usernameSchema,
84
84
  }),
85
85
  responses: {
86
- 200: apiSuccess(c.noBody()),
86
+ 204: apiSuccess(c.noBody()),
87
87
  400: ZodErrorSchema,
88
88
  401: apiError(z.literal("UNAUTHORIZED"), z.string()),
89
89
  500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
@@ -98,7 +98,7 @@ export default c.router({
98
98
  roundBorder: z.boolean(),
99
99
  }),
100
100
  responses: {
101
- 200: apiSuccess(c.noBody()),
101
+ 204: apiSuccess(c.noBody()),
102
102
  400: ZodErrorSchema,
103
103
  401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
104
104
  500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./client.js";
2
2
  export * from "./server.js";
3
+ export * from "./otp.js";
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./client.js";
2
2
  export * from "./server.js";
3
+ export * from "./otp.js";
package/dist/otp.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function generateOTP(secret: string): Promise<string>;
2
+ export declare function verifyOTP(token: string, secret: string): Promise<boolean>;
package/dist/otp.js ADDED
@@ -0,0 +1,7 @@
1
+ import { verify, generate } from "otplib";
2
+ export async function generateOTP(secret) {
3
+ return generate({ secret });
4
+ }
5
+ export async function verifyOTP(token, secret) {
6
+ return verify({ token, secret }).then((res) => res.valid);
7
+ }
package/dist/server.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- export * from "./common.js";
2
1
  import { ResultAsync } from "neverthrow";
3
2
  import type { Time } from "@darco2903/secondthought";
4
3
  import type { CdnAssetTokenData } from "@darco2903/cdn-api/server";
5
4
  import { type JWTVerifyError, type AccessTokenData, type AccessTokenDataDecoded, type JWTSignError } from "./types/index.js";
5
+ export * from "./common.js";
6
+ export { verifyOTP } from "./otp.js";
6
7
  export declare function JWTVerify(token: string, pubKey: string): ResultAsync<AccessTokenDataDecoded, JWTVerifyError>;
7
8
  /**
8
9
  * Sign a JWT token with the given payload and private key, with the specified expiration time.
package/dist/server.js CHANGED
@@ -1,8 +1,9 @@
1
- export * from "./common.js";
2
1
  import jwt from "jsonwebtoken";
3
2
  import { ResultAsync } from "neverthrow";
4
3
  import { accessTokenDataDecodedSchema, } from "./types/index.js";
5
4
  import { JWT_ALGORITHM, JWT_ALGORITHMS } from "./consts.js";
5
+ export * from "./common.js";
6
+ export { verifyOTP } from "./otp.js";
6
7
  export function JWTVerify(token, pubKey) {
7
8
  return ResultAsync.fromPromise(new Promise((resolve, reject) => {
8
9
  jwt.verify(token, pubKey, { algorithms: JWT_ALGORITHMS }, (e, decoded) => {
@@ -23,4 +23,21 @@ export declare const accessRefreshSchema: z.ZodObject<{
23
23
  expiresIn: number;
24
24
  refreshToken: string;
25
25
  }>;
26
+ export declare const accessRefreshPendingSchema: z.ZodObject<{
27
+ accessToken: z.ZodString;
28
+ expiresIn: z.ZodNumber;
29
+ } & {
30
+ refreshToken: z.ZodNullable<z.ZodString>;
31
+ needTotp: z.ZodBoolean;
32
+ }, "strip", z.ZodTypeAny, {
33
+ accessToken: string;
34
+ expiresIn: number;
35
+ refreshToken: string | null;
36
+ needTotp: boolean;
37
+ }, {
38
+ accessToken: string;
39
+ expiresIn: number;
40
+ refreshToken: string | null;
41
+ needTotp: boolean;
42
+ }>;
26
43
  export declare const totpCodeSchema: z.ZodString;
@@ -6,4 +6,8 @@ export const accessSchema = z.object({
6
6
  export const accessRefreshSchema = accessSchema.extend({
7
7
  refreshToken: z.string(),
8
8
  });
9
+ export const accessRefreshPendingSchema = accessSchema.extend({
10
+ refreshToken: z.string().nullable(),
11
+ needTotp: z.boolean(),
12
+ });
9
13
  export const totpCodeSchema = z.string().min(6).max(6);
@@ -50,6 +50,7 @@ export declare const userSchema: z.ZodObject<{
50
50
  email: z.ZodString;
51
51
  role: z.ZodNumber;
52
52
  verified: z.ZodBoolean;
53
+ totp_enabled: z.ZodBoolean;
53
54
  last_login: z.ZodNullable<z.ZodDate>;
54
55
  created_at: z.ZodDate;
55
56
  updated_at: z.ZodDate;
@@ -65,6 +66,7 @@ export declare const userSchema: z.ZodObject<{
65
66
  };
66
67
  round_border: boolean;
67
68
  verified: boolean;
69
+ totp_enabled: boolean;
68
70
  last_login: Date | null;
69
71
  created_at: Date;
70
72
  updated_at: Date;
@@ -80,6 +82,7 @@ export declare const userSchema: z.ZodObject<{
80
82
  };
81
83
  round_border: boolean;
82
84
  verified: boolean;
85
+ totp_enabled: boolean;
83
86
  last_login: Date | null;
84
87
  created_at: Date;
85
88
  updated_at: Date;
@@ -18,6 +18,7 @@ export const userSchema = userPublicSchema.extend({
18
18
  email: z.string().email(),
19
19
  role: z.number().int().min(-1, "Invalid level").max(255, "Invalid level"),
20
20
  verified: z.boolean(),
21
+ totp_enabled: z.boolean(),
21
22
  last_login: z.date().nullable(),
22
23
  created_at: z.date(),
23
24
  updated_at: z.date(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darco2903/auth-api",
3
- "version": "2.1.4",
3
+ "version": "2.2.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -19,19 +19,20 @@
19
19
  "./server": "./dist/server.js"
20
20
  },
21
21
  "dependencies": {
22
- "@darco2903/cdn-api": "^1.1.0",
22
+ "@darco2903/cdn-api": "^1.2.0",
23
23
  "@ts-rest/core": "^3.52.1",
24
24
  "@ts-rest/open-api": "^3.52.1",
25
25
  "jsonwebtoken": "^9.0.3",
26
26
  "neverthrow": "^8.2.0",
27
+ "otplib": "^13.4.0",
27
28
  "zod": "^3.25.76"
28
29
  },
29
30
  "peerDependencies": {
30
- "@darco2903/secondthought": "^1.1.0"
31
+ "@darco2903/secondthought": "^1.3.0"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/jsonwebtoken": "^9.0.10",
34
- "@types/node": "^25.4.0",
35
+ "@types/node": "^24.12.2",
35
36
  "prettier": "^3.8.1",
36
37
  "rimraf": "^6.1.3",
37
38
  "tsx": "^4.21.0",