nextjs-hasura-auth 0.1.2 → 0.1.4

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,94 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.generateVerificationToken = generateVerificationToken;
16
+ exports.verifyVerificationToken = verifyVerificationToken;
17
+ const jose_1 = require("jose");
18
+ const debug_1 = __importDefault(require("@/lib/debug"));
19
+ const jwt_1 = require("./jwt"); // Reuse the hashed NEXTAUTH_SECRET for simplicity
20
+ const debug = (0, debug_1.default)('tokenUtils');
21
+ // Use the same secret as NextAuth JWE for simplicity, but hashed.
22
+ // Alternatively, generate a separate secret for verification tokens.
23
+ let verificationSecretPromise = null;
24
+ const getVerificationSecret = () => {
25
+ if (!verificationSecretPromise) {
26
+ verificationSecretPromise = (0, jwt_1.getNextAuthSecret)();
27
+ }
28
+ return verificationSecretPromise;
29
+ };
30
+ const VERIFICATION_TOKEN_EXPIRY = '1h'; // Verification token valid for 1 hour
31
+ const JWT_ALGORITHM = 'HS256'; // Algorithm for signing
32
+ /**
33
+ * Generates a short-lived JWT for email verification.
34
+ * @param userId - The ID of the user to verify.
35
+ * @returns Promise<string> - The generated verification token.
36
+ */
37
+ function generateVerificationToken(userId) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ debug('Generating verification token for user: %s', userId);
40
+ try {
41
+ const secret = yield getVerificationSecret();
42
+ const token = yield new jose_1.SignJWT({ scope: 'verify_email' }) // Add scope for clarity
43
+ .setProtectedHeader({ alg: JWT_ALGORITHM })
44
+ .setSubject(userId) // Embed userId in 'sub' claim
45
+ .setIssuedAt()
46
+ .setExpirationTime(VERIFICATION_TOKEN_EXPIRY)
47
+ .sign(secret);
48
+ debug('Verification token generated successfully.');
49
+ return token;
50
+ }
51
+ catch (error) {
52
+ debug('Error generating verification token:', error);
53
+ console.error('Failed to generate verification token:', error);
54
+ throw new Error('Could not generate verification token.');
55
+ }
56
+ });
57
+ }
58
+ /**
59
+ * Verifies an email verification token.
60
+ * @param token - The token string to verify.
61
+ * @returns Promise<{ userId: string } | null> - The user ID if the token is valid and has the correct scope, otherwise null.
62
+ */
63
+ function verifyVerificationToken(token) {
64
+ return __awaiter(this, void 0, void 0, function* () {
65
+ debug('Verifying verification token...');
66
+ if (!token) {
67
+ debug('Verification token is missing.');
68
+ return null;
69
+ }
70
+ try {
71
+ const secret = yield getVerificationSecret();
72
+ const { payload } = yield (0, jose_1.jwtVerify)(token, secret, {
73
+ algorithms: [JWT_ALGORITHM],
74
+ });
75
+ // Check for specific scope if needed (good practice)
76
+ if (payload.scope !== 'verify_email') {
77
+ debug('Verification token has invalid scope: %s', payload.scope);
78
+ return null;
79
+ }
80
+ const userId = payload.sub;
81
+ if (!userId) {
82
+ debug('Verification token is missing user ID (sub claim).');
83
+ return null;
84
+ }
85
+ debug('Verification token verified successfully for user: %s', userId);
86
+ return { userId };
87
+ }
88
+ catch (error) {
89
+ // Errors like expired token, invalid signature, etc.
90
+ debug('Error verifying verification token:', error.code || error.message);
91
+ return null; // Return null for any verification error
92
+ }
93
+ });
94
+ }
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nextjs-hasura-auth",
3
3
  "shortName": "nha",
4
- "version": "0.1.1",
4
+ "version": "0.1.4",
5
5
  "engines": {
6
6
  "node": "22.14"
7
7
  },
@@ -20,10 +20,11 @@
20
20
  "test:build": "jest build.test.ts",
21
21
  "postinstall": "npm run ws -- -y",
22
22
  "ws": "npx --yes next-ws-cli@latest patch",
23
- "nha:migrate": "tsx ./migrations/nha/up.ts",
23
+ "nha:migrate": "tsx ./migrations/nha/up.ts; npm run hasura:schema; npm run hasura:types",
24
24
  "nha:unmigrate": "tsx ./migrations/nha/down.ts",
25
25
  "hasura:schema": "tsx ./lib/hasura-schema.ts",
26
- "codegen": "graphql-codegen --config codegen.ts"
26
+ "hasura:types": "graphql-codegen --config codegen.ts",
27
+ "publish": "npm run hasura:schema; npm run hasura:types; npm run build; npm publish"
27
28
  },
28
29
  "main": "dist/lib/index.js",
29
30
  "types": "dist/lib/index.d.ts",
@@ -64,7 +65,9 @@
64
65
  "@radix-ui/react-toggle": "^1.1.3",
65
66
  "@radix-ui/react-toggle-group": "^1.1.3",
66
67
  "@radix-ui/react-tooltip": "^1.2.0",
68
+ "@types/bcrypt": "^5.0.2",
67
69
  "@types/debug": "^4.1.12",
70
+ "bcrypt": "^5.1.1",
68
71
  "class-variance-authority": "^0.7.1",
69
72
  "clsx": "^2.1.1",
70
73
  "cmdk": "^1.1.1",
@@ -89,12 +92,13 @@
89
92
  "react-hook-form": "^7.55.0",
90
93
  "react-resizable-panels": "^2.1.7",
91
94
  "recharts": "^2.15.3",
95
+ "resend": "^4.3.0",
92
96
  "sonner": "^2.0.3",
93
97
  "tailwind-merge": "^3.2.0",
98
+ "ts-essentials": "^10.0.4",
94
99
  "tw-animate-css": "^1.2.5",
95
100
  "uuid": "^11.1.0",
96
101
  "vaul": "^1.1.2",
97
- "zerobounce": "^0.3.0",
98
102
  "zod": "^3.24.3"
99
103
  },
100
104
  "devDependencies": {