nextjs-hasura-auth 0.1.1 → 0.1.3
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/APOLLO.md +101 -174
- package/GENERATOR.md +4 -5
- package/README.md +9 -5
- package/dist/lib/apollo.d.ts +11 -9
- package/dist/lib/apollo.js +127 -90
- package/dist/lib/auth.d.ts +16 -0
- package/dist/lib/auth.js +159 -0
- package/dist/lib/authDbUtils.d.ts +48 -0
- package/dist/lib/authDbUtils.js +183 -0
- package/dist/lib/client.d.ts +81 -0
- package/dist/lib/client.js +353 -0
- package/dist/lib/email.d.ts +7 -0
- package/dist/lib/email.js +90 -0
- package/dist/lib/generator.d.ts +2 -7
- package/dist/lib/generator.js +394 -392
- package/dist/lib/graphql-proxy.d.ts +6 -0
- package/dist/lib/graphql-proxy.js +385 -0
- package/dist/lib/hasura-schema.d.ts +1 -0
- package/dist/lib/hasura-schema.js +65 -0
- package/dist/lib/hasura.d.ts +16 -0
- package/dist/lib/hasura.js +102 -0
- package/dist/lib/hooks/useCheckConnection.d.ts +7 -0
- package/dist/lib/hooks/useCheckConnection.js +62 -0
- package/dist/lib/index.d.ts +5 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/test-utils.d.ts +11 -0
- package/dist/lib/test-utils.js +59 -0
- package/dist/lib/tokenUtils.d.ts +14 -0
- package/dist/lib/tokenUtils.js +94 -0
- package/dist/package.json +22 -4
- package/dist/public/hasura-schema.json +7995 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +17 -6
package/dist/lib/index.js
CHANGED
@@ -18,3 +18,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
__exportStar(require("./utils"), exports);
|
19
19
|
__exportStar(require("./apollo"), exports);
|
20
20
|
__exportStar(require("./generator"), exports);
|
21
|
+
__exportStar(require("./hasura"), exports);
|
22
|
+
__exportStar(require("./auth"), exports);
|
23
|
+
__exportStar(require("./client"), exports);
|
24
|
+
__exportStar(require("./jwt"), exports);
|
25
|
+
__exportStar(require("./graphql-proxy"), exports);
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { ReactElement } from 'react';
|
2
|
+
import { screen } from '@testing-library/react';
|
3
|
+
import { ApolloClient } from '@apollo/client';
|
4
|
+
/**
|
5
|
+
* Custom renderer that wraps the component with necessary providers
|
6
|
+
*/
|
7
|
+
declare const customRender: (ui: ReactElement, { apolloClient, ...renderOptions }?: {
|
8
|
+
apolloClient?: ApolloClient<import("@apollo/client").NormalizedCacheObject> | undefined;
|
9
|
+
}) => import("@testing-library/react").RenderResult<typeof import("@testing-library/dom/types/queries"), HTMLElement, HTMLElement>;
|
10
|
+
export * from '@testing-library/react';
|
11
|
+
export { customRender as render, screen };
|
@@ -0,0 +1,59 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
17
|
+
var t = {};
|
18
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
19
|
+
t[p] = s[p];
|
20
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
21
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
22
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
23
|
+
t[p[i]] = s[p[i]];
|
24
|
+
}
|
25
|
+
return t;
|
26
|
+
};
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
28
|
+
exports.screen = exports.render = void 0;
|
29
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
30
|
+
const react_1 = require("@testing-library/react");
|
31
|
+
Object.defineProperty(exports, "screen", { enumerable: true, get: function () { return react_1.screen; } });
|
32
|
+
const client_1 = require("@apollo/client");
|
33
|
+
// Create a mock Apollo client for testing
|
34
|
+
const createMockClient = () => {
|
35
|
+
return new client_1.ApolloClient({
|
36
|
+
cache: new client_1.InMemoryCache(),
|
37
|
+
defaultOptions: {
|
38
|
+
watchQuery: {
|
39
|
+
fetchPolicy: 'no-cache',
|
40
|
+
},
|
41
|
+
query: {
|
42
|
+
fetchPolicy: 'no-cache',
|
43
|
+
},
|
44
|
+
},
|
45
|
+
});
|
46
|
+
};
|
47
|
+
/**
|
48
|
+
* Custom renderer that wraps the component with necessary providers
|
49
|
+
*/
|
50
|
+
const customRender = (ui, _a = {}) => {
|
51
|
+
var { apolloClient = createMockClient() } = _a, renderOptions = __rest(_a, ["apolloClient"]);
|
52
|
+
const AllTheProviders = ({ children }) => {
|
53
|
+
return ((0, jsx_runtime_1.jsx)(client_1.ApolloProvider, { client: apolloClient, children: children }));
|
54
|
+
};
|
55
|
+
return (0, react_1.render)(ui, Object.assign({ wrapper: AllTheProviders }, renderOptions));
|
56
|
+
};
|
57
|
+
exports.render = customRender;
|
58
|
+
// re-export everything from testing-library
|
59
|
+
__exportStar(require("@testing-library/react"), exports);
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* Generates a short-lived JWT for email verification.
|
3
|
+
* @param userId - The ID of the user to verify.
|
4
|
+
* @returns Promise<string> - The generated verification token.
|
5
|
+
*/
|
6
|
+
export declare function generateVerificationToken(userId: string): Promise<string>;
|
7
|
+
/**
|
8
|
+
* Verifies an email verification token.
|
9
|
+
* @param token - The token string to verify.
|
10
|
+
* @returns Promise<{ userId: string } | null> - The user ID if the token is valid and has the correct scope, otherwise null.
|
11
|
+
*/
|
12
|
+
export declare function verifyVerificationToken(token: string): Promise<{
|
13
|
+
userId: string;
|
14
|
+
} | null>;
|
@@ -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.
|
4
|
+
"version": "0.1.3",
|
5
5
|
"engines": {
|
6
6
|
"node": "22.14"
|
7
7
|
},
|
@@ -11,15 +11,20 @@
|
|
11
11
|
},
|
12
12
|
"scripts": {
|
13
13
|
"dev": "next dev --turbopack",
|
14
|
-
"build": "
|
15
|
-
"build:lib": "tsc -p tsconfig.lib.json",
|
14
|
+
"build": "npm run build:lib && next build",
|
15
|
+
"build:lib": "rm -rf dist && tsc -p tsconfig.lib.json",
|
16
16
|
"build:next": "next build --turbopack",
|
17
17
|
"start": "next start --turbopack",
|
18
18
|
"lint": "next lint --turbopack",
|
19
19
|
"test": "jest",
|
20
20
|
"test:build": "jest build.test.ts",
|
21
21
|
"postinstall": "npm run ws -- -y",
|
22
|
-
"ws": "npx --yes next-ws-cli@latest patch"
|
22
|
+
"ws": "npx --yes next-ws-cli@latest patch",
|
23
|
+
"nha:migrate": "tsx ./migrations/nha/up.ts; npm run hasura:schema; npm run hasura:types",
|
24
|
+
"nha:unmigrate": "tsx ./migrations/nha/down.ts",
|
25
|
+
"hasura:schema": "tsx ./lib/hasura-schema.ts",
|
26
|
+
"hasura:types": "graphql-codegen --config codegen.ts",
|
27
|
+
"publish": "npm run hasura:schema; npm run hasura:types; npm run build; npm publish"
|
23
28
|
},
|
24
29
|
"main": "dist/lib/index.js",
|
25
30
|
"types": "dist/lib/index.d.ts",
|
@@ -60,7 +65,9 @@
|
|
60
65
|
"@radix-ui/react-toggle": "^1.1.3",
|
61
66
|
"@radix-ui/react-toggle-group": "^1.1.3",
|
62
67
|
"@radix-ui/react-tooltip": "^1.2.0",
|
68
|
+
"@types/bcrypt": "^5.0.2",
|
63
69
|
"@types/debug": "^4.1.12",
|
70
|
+
"bcrypt": "^5.1.1",
|
64
71
|
"class-variance-authority": "^0.7.1",
|
65
72
|
"clsx": "^2.1.1",
|
66
73
|
"cmdk": "^1.1.1",
|
@@ -85,9 +92,12 @@
|
|
85
92
|
"react-hook-form": "^7.55.0",
|
86
93
|
"react-resizable-panels": "^2.1.7",
|
87
94
|
"recharts": "^2.15.3",
|
95
|
+
"resend": "^4.3.0",
|
88
96
|
"sonner": "^2.0.3",
|
89
97
|
"tailwind-merge": "^3.2.0",
|
98
|
+
"ts-essentials": "^10.0.4",
|
90
99
|
"tw-animate-css": "^1.2.5",
|
100
|
+
"uuid": "^11.1.0",
|
91
101
|
"vaul": "^1.1.2",
|
92
102
|
"zod": "^3.24.3"
|
93
103
|
},
|
@@ -96,7 +106,12 @@
|
|
96
106
|
"@babel/preset-env": "^7.26.9",
|
97
107
|
"@babel/preset-react": "^7.26.3",
|
98
108
|
"@babel/preset-typescript": "^7.27.0",
|
109
|
+
"@deep-foundation/hasura": "^0.0.68",
|
110
|
+
"@graphql-codegen/cli": "^5.0.5",
|
111
|
+
"@graphql-codegen/typescript": "^4.1.6",
|
99
112
|
"@jest/globals": "^29.7.0",
|
113
|
+
"@swc/core": "^1.11.21",
|
114
|
+
"@swc/jest": "^0.2.37",
|
100
115
|
"@tailwindcss/postcss": "^4",
|
101
116
|
"@testing-library/jest-dom": "^6.4.0",
|
102
117
|
"@testing-library/react": "^15.0.0",
|
@@ -109,8 +124,11 @@
|
|
109
124
|
"babel-jest": "^29.7.0",
|
110
125
|
"jest": "^29.7.0",
|
111
126
|
"jest-environment-jsdom": "^29.7.0",
|
127
|
+
"prettier": "^3.5.3",
|
112
128
|
"tailwindcss": "^4",
|
113
129
|
"ts-jest": "^29.1.2",
|
130
|
+
"ts-node": "^10.9.2",
|
131
|
+
"tsx": "^4.19.3",
|
114
132
|
"typescript": "^5"
|
115
133
|
}
|
116
134
|
}
|