mailsentry-auth 0.1.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,225 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/services/utils/cookie-utils.ts
2
+ var _jscookie = require('js-cookie'); var _jscookie2 = _interopRequireDefault(_jscookie);
3
+ var _CookieUtils = class _CookieUtils {
4
+ /**
5
+ * Get the access token cookie key from environment variables
6
+ */
7
+ static getAccessTokenKey() {
8
+ return process.env.AUTH_ACCESS_TOKEN_KEY || "auth_access_token";
9
+ }
10
+ /**
11
+ * Get the refresh token cookie key from environment variables
12
+ */
13
+ static getRefreshTokenKey() {
14
+ return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
15
+ }
16
+ // Use current domain in development
17
+ /**
18
+ * Get root domain for subdomain support
19
+ */
20
+ static getRootDomain() {
21
+ if (typeof window === "undefined") return void 0;
22
+ const hostname = window.location.hostname;
23
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
24
+ return void 0;
25
+ }
26
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
27
+ return void 0;
28
+ }
29
+ const parts = hostname.split(".");
30
+ if (parts.length >= 2) {
31
+ return `.${parts.slice(-2).join(".")}`;
32
+ }
33
+ return void 0;
34
+ }
35
+ /**
36
+ * Get common cookie options
37
+ */
38
+ static getCookieOptions() {
39
+ return {
40
+ path: "/",
41
+ sameSite: "strict",
42
+ secure: process.env.NODE_ENV === "production",
43
+ // Only secure in production
44
+ domain: this.COOKIE_DOMAIN
45
+ // Support subdomains
46
+ };
47
+ }
48
+ /**
49
+ * Check if running on client side
50
+ */
51
+ static isClientSide() {
52
+ return typeof window !== "undefined";
53
+ }
54
+ /**
55
+ * Check if running on server side
56
+ */
57
+ static isServerSide() {
58
+ return typeof window === "undefined";
59
+ }
60
+ /**
61
+ * Dynamically import server action for server-side operations
62
+ */
63
+ static async getServerTokens() {
64
+ try {
65
+ const { getAuthTokens } = await Promise.resolve().then(() => _interopRequireWildcard(require("mailsentry-auth/server")));
66
+ return await getAuthTokens();
67
+ } catch (error) {
68
+ console.error("Failed to get server tokens:", error);
69
+ return { accessToken: null, refreshToken: null };
70
+ }
71
+ }
72
+ /**
73
+ * Set access token in cookie (client-side only)
74
+ */
75
+ static setAccessToken(token) {
76
+ if (this.isServerSide()) {
77
+ console.warn("setAccessToken called on server side - use server actions instead");
78
+ return;
79
+ }
80
+ const options = this.getCookieOptions();
81
+ _jscookie2.default.set(this.getAccessTokenKey(), token, options);
82
+ }
83
+ /**
84
+ * Set refresh token in cookie (client-side only)
85
+ */
86
+ static setRefreshToken(token) {
87
+ if (this.isServerSide()) {
88
+ console.warn("setRefreshToken called on server side - use server actions instead");
89
+ return;
90
+ }
91
+ const options = this.getCookieOptions();
92
+ _jscookie2.default.set(this.getRefreshTokenKey(), token, options);
93
+ }
94
+ /**
95
+ * Get access token - automatically handles client/server side
96
+ */
97
+ static async getAccessToken() {
98
+ if (this.isClientSide()) {
99
+ return _jscookie2.default.get(this.getAccessTokenKey()) || null;
100
+ } else {
101
+ const { accessToken } = await this.getServerTokens();
102
+ return accessToken;
103
+ }
104
+ }
105
+ /**
106
+ * Get refresh token - automatically handles client/server side
107
+ */
108
+ static async getRefreshToken() {
109
+ if (this.isClientSide()) {
110
+ return _jscookie2.default.get(this.getRefreshTokenKey()) || null;
111
+ } else {
112
+ const { refreshToken } = await this.getServerTokens();
113
+ return refreshToken;
114
+ }
115
+ }
116
+ /**
117
+ * Get both tokens - automatically handles client/server side
118
+ */
119
+ static async getTokens() {
120
+ if (this.isClientSide()) {
121
+ return {
122
+ accessToken: _jscookie2.default.get(this.getAccessTokenKey()) || null,
123
+ refreshToken: _jscookie2.default.get(this.getRefreshTokenKey()) || null
124
+ };
125
+ } else {
126
+ return await this.getServerTokens();
127
+ }
128
+ }
129
+ /**
130
+ * Clear all authentication cookies (client-side only)
131
+ */
132
+ static clearAuthCookies() {
133
+ if (this.isServerSide()) {
134
+ console.warn("clearAuthCookies called on server side - use server actions instead");
135
+ return;
136
+ }
137
+ const removeOptions = {
138
+ path: "/",
139
+ domain: this.COOKIE_DOMAIN
140
+ };
141
+ _jscookie2.default.remove(this.getAccessTokenKey(), removeOptions);
142
+ _jscookie2.default.remove(this.getRefreshTokenKey(), removeOptions);
143
+ }
144
+ /**
145
+ * Check if cookies are supported/enabled (client-side only)
146
+ */
147
+ static areCookiesEnabled() {
148
+ if (this.isServerSide()) {
149
+ console.warn("areCookiesEnabled called on server side - not applicable");
150
+ return false;
151
+ }
152
+ try {
153
+ const testKey = "test_cookie_support";
154
+ const testOptions = this.getCookieOptions();
155
+ _jscookie2.default.set(testKey, "test", testOptions);
156
+ const value = _jscookie2.default.get(testKey);
157
+ _jscookie2.default.remove(testKey, {
158
+ path: "/",
159
+ domain: this.COOKIE_DOMAIN
160
+ });
161
+ return value === "test";
162
+ } catch (e) {
163
+ return false;
164
+ }
165
+ }
166
+ /**
167
+ * Get all authentication cookies - automatically handles client/server side
168
+ */
169
+ static async getAllAuthCookies() {
170
+ if (this.isClientSide()) {
171
+ return {
172
+ accessToken: _jscookie2.default.get(this.getAccessTokenKey()) || "",
173
+ refreshToken: _jscookie2.default.get(this.getRefreshTokenKey()) || ""
174
+ };
175
+ } else {
176
+ const { accessToken, refreshToken } = await this.getServerTokens();
177
+ return {
178
+ accessToken: accessToken || "",
179
+ refreshToken: refreshToken || ""
180
+ };
181
+ }
182
+ }
183
+ /**
184
+ * Set multiple tokens at once (client-side only)
185
+ */
186
+ static setTokens(accessToken, refreshToken) {
187
+ if (this.isServerSide()) {
188
+ console.warn("setTokens called on server side - use server actions instead");
189
+ return;
190
+ }
191
+ this.setAccessToken(accessToken);
192
+ this.setRefreshToken(refreshToken);
193
+ }
194
+ /**
195
+ * Check if user has valid tokens - automatically handles client/server side
196
+ */
197
+ static async hasValidTokens() {
198
+ const tokens = await this.getTokens();
199
+ return !!(tokens.accessToken && tokens.refreshToken);
200
+ }
201
+ /**
202
+ * Get current domain information for debugging
203
+ */
204
+ static getDomainInfo() {
205
+ if (this.isServerSide()) {
206
+ return {
207
+ error: "Server-side rendering - no domain info available",
208
+ environment: process.env.NODE_ENV || "unknown",
209
+ recommendation: "Use server actions for server-side cookie access"
210
+ };
211
+ }
212
+ return {
213
+ hostname: window.location.hostname,
214
+ domain: this.COOKIE_DOMAIN || "current domain",
215
+ environment: process.env.NODE_ENV || "unknown",
216
+ protocol: window.location.protocol
217
+ };
218
+ }
219
+ };
220
+ // Domain configuration
221
+ _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
222
+ var CookieUtils = _CookieUtils;
223
+
224
+
225
+ exports.CookieUtils = CookieUtils;
@@ -0,0 +1,225 @@
1
+ // src/services/utils/cookie-utils.ts
2
+ import Cookies from "js-cookie";
3
+ var _CookieUtils = class _CookieUtils {
4
+ /**
5
+ * Get the access token cookie key from environment variables
6
+ */
7
+ static getAccessTokenKey() {
8
+ return process.env.AUTH_ACCESS_TOKEN_KEY || "auth_access_token";
9
+ }
10
+ /**
11
+ * Get the refresh token cookie key from environment variables
12
+ */
13
+ static getRefreshTokenKey() {
14
+ return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
15
+ }
16
+ // Use current domain in development
17
+ /**
18
+ * Get root domain for subdomain support
19
+ */
20
+ static getRootDomain() {
21
+ if (typeof window === "undefined") return void 0;
22
+ const hostname = window.location.hostname;
23
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
24
+ return void 0;
25
+ }
26
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
27
+ return void 0;
28
+ }
29
+ const parts = hostname.split(".");
30
+ if (parts.length >= 2) {
31
+ return `.${parts.slice(-2).join(".")}`;
32
+ }
33
+ return void 0;
34
+ }
35
+ /**
36
+ * Get common cookie options
37
+ */
38
+ static getCookieOptions() {
39
+ return {
40
+ path: "/",
41
+ sameSite: "strict",
42
+ secure: process.env.NODE_ENV === "production",
43
+ // Only secure in production
44
+ domain: this.COOKIE_DOMAIN
45
+ // Support subdomains
46
+ };
47
+ }
48
+ /**
49
+ * Check if running on client side
50
+ */
51
+ static isClientSide() {
52
+ return typeof window !== "undefined";
53
+ }
54
+ /**
55
+ * Check if running on server side
56
+ */
57
+ static isServerSide() {
58
+ return typeof window === "undefined";
59
+ }
60
+ /**
61
+ * Dynamically import server action for server-side operations
62
+ */
63
+ static async getServerTokens() {
64
+ try {
65
+ const { getAuthTokens } = await import("mailsentry-auth/server");
66
+ return await getAuthTokens();
67
+ } catch (error) {
68
+ console.error("Failed to get server tokens:", error);
69
+ return { accessToken: null, refreshToken: null };
70
+ }
71
+ }
72
+ /**
73
+ * Set access token in cookie (client-side only)
74
+ */
75
+ static setAccessToken(token) {
76
+ if (this.isServerSide()) {
77
+ console.warn("setAccessToken called on server side - use server actions instead");
78
+ return;
79
+ }
80
+ const options = this.getCookieOptions();
81
+ Cookies.set(this.getAccessTokenKey(), token, options);
82
+ }
83
+ /**
84
+ * Set refresh token in cookie (client-side only)
85
+ */
86
+ static setRefreshToken(token) {
87
+ if (this.isServerSide()) {
88
+ console.warn("setRefreshToken called on server side - use server actions instead");
89
+ return;
90
+ }
91
+ const options = this.getCookieOptions();
92
+ Cookies.set(this.getRefreshTokenKey(), token, options);
93
+ }
94
+ /**
95
+ * Get access token - automatically handles client/server side
96
+ */
97
+ static async getAccessToken() {
98
+ if (this.isClientSide()) {
99
+ return Cookies.get(this.getAccessTokenKey()) || null;
100
+ } else {
101
+ const { accessToken } = await this.getServerTokens();
102
+ return accessToken;
103
+ }
104
+ }
105
+ /**
106
+ * Get refresh token - automatically handles client/server side
107
+ */
108
+ static async getRefreshToken() {
109
+ if (this.isClientSide()) {
110
+ return Cookies.get(this.getRefreshTokenKey()) || null;
111
+ } else {
112
+ const { refreshToken } = await this.getServerTokens();
113
+ return refreshToken;
114
+ }
115
+ }
116
+ /**
117
+ * Get both tokens - automatically handles client/server side
118
+ */
119
+ static async getTokens() {
120
+ if (this.isClientSide()) {
121
+ return {
122
+ accessToken: Cookies.get(this.getAccessTokenKey()) || null,
123
+ refreshToken: Cookies.get(this.getRefreshTokenKey()) || null
124
+ };
125
+ } else {
126
+ return await this.getServerTokens();
127
+ }
128
+ }
129
+ /**
130
+ * Clear all authentication cookies (client-side only)
131
+ */
132
+ static clearAuthCookies() {
133
+ if (this.isServerSide()) {
134
+ console.warn("clearAuthCookies called on server side - use server actions instead");
135
+ return;
136
+ }
137
+ const removeOptions = {
138
+ path: "/",
139
+ domain: this.COOKIE_DOMAIN
140
+ };
141
+ Cookies.remove(this.getAccessTokenKey(), removeOptions);
142
+ Cookies.remove(this.getRefreshTokenKey(), removeOptions);
143
+ }
144
+ /**
145
+ * Check if cookies are supported/enabled (client-side only)
146
+ */
147
+ static areCookiesEnabled() {
148
+ if (this.isServerSide()) {
149
+ console.warn("areCookiesEnabled called on server side - not applicable");
150
+ return false;
151
+ }
152
+ try {
153
+ const testKey = "test_cookie_support";
154
+ const testOptions = this.getCookieOptions();
155
+ Cookies.set(testKey, "test", testOptions);
156
+ const value = Cookies.get(testKey);
157
+ Cookies.remove(testKey, {
158
+ path: "/",
159
+ domain: this.COOKIE_DOMAIN
160
+ });
161
+ return value === "test";
162
+ } catch (e) {
163
+ return false;
164
+ }
165
+ }
166
+ /**
167
+ * Get all authentication cookies - automatically handles client/server side
168
+ */
169
+ static async getAllAuthCookies() {
170
+ if (this.isClientSide()) {
171
+ return {
172
+ accessToken: Cookies.get(this.getAccessTokenKey()) || "",
173
+ refreshToken: Cookies.get(this.getRefreshTokenKey()) || ""
174
+ };
175
+ } else {
176
+ const { accessToken, refreshToken } = await this.getServerTokens();
177
+ return {
178
+ accessToken: accessToken || "",
179
+ refreshToken: refreshToken || ""
180
+ };
181
+ }
182
+ }
183
+ /**
184
+ * Set multiple tokens at once (client-side only)
185
+ */
186
+ static setTokens(accessToken, refreshToken) {
187
+ if (this.isServerSide()) {
188
+ console.warn("setTokens called on server side - use server actions instead");
189
+ return;
190
+ }
191
+ this.setAccessToken(accessToken);
192
+ this.setRefreshToken(refreshToken);
193
+ }
194
+ /**
195
+ * Check if user has valid tokens - automatically handles client/server side
196
+ */
197
+ static async hasValidTokens() {
198
+ const tokens = await this.getTokens();
199
+ return !!(tokens.accessToken && tokens.refreshToken);
200
+ }
201
+ /**
202
+ * Get current domain information for debugging
203
+ */
204
+ static getDomainInfo() {
205
+ if (this.isServerSide()) {
206
+ return {
207
+ error: "Server-side rendering - no domain info available",
208
+ environment: process.env.NODE_ENV || "unknown",
209
+ recommendation: "Use server actions for server-side cookie access"
210
+ };
211
+ }
212
+ return {
213
+ hostname: window.location.hostname,
214
+ domain: this.COOKIE_DOMAIN || "current domain",
215
+ environment: process.env.NODE_ENV || "unknown",
216
+ protocol: window.location.protocol
217
+ };
218
+ }
219
+ };
220
+ // Domain configuration
221
+ _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
222
+ var CookieUtils = _CookieUtils;
223
+ export {
224
+ CookieUtils
225
+ };
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "mailsentry-auth",
3
+ "version": "0.1.0",
4
+ "description": "Next.js 15 authentication package with multi-step auth flow, cross-tab sync, and Zustand state management",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./middleware": {
15
+ "types": "./dist/middleware.d.ts",
16
+ "import": "./dist/middleware.mjs"
17
+ },
18
+ "./server": {
19
+ "types": "./src/app/actions/index.ts",
20
+ "import": "./src/app/actions/index.ts",
21
+ "require": "./src/app/actions/index.ts"
22
+ },
23
+ "./utils": {
24
+ "import": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/utils/cookie-utils.mjs"
27
+ },
28
+ "require": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/utils/cookie-utils.js"
31
+ }
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "dist/utils",
37
+ "src/app/actions",
38
+ "README.md",
39
+ "ZUSTAND_MIGRATION.md"
40
+ ],
41
+ "scripts": {
42
+ "dev": "next dev --turbopack",
43
+ "build": "next build",
44
+ "build:package": "tsup",
45
+ "build:package:watch": "tsup --watch",
46
+ "build:link": "npm run build:package && npm link",
47
+ "link:sample": "cd ../nextjs-sample && npm link mailsentry-auth",
48
+ "build:link:sample": "npm run build:link && npm run link:sample",
49
+ "link:cutly": "cd ../cutly && pnpm link ../auth-nextjs",
50
+ "build:link:cutly": "pnpm run build:package && pnpm run link:cutly",
51
+ "start": "next start",
52
+ "lint": "next lint",
53
+ "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,scss}\"",
54
+ "prepublishOnly": "npm run build:package"
55
+ },
56
+ "peerDependencies": {
57
+ "next": ">=15.0.0",
58
+ "react": ">=18.0.0 || >=19.0.0",
59
+ "react-dom": ">=18.0.0 || >=19.0.0"
60
+ },
61
+ "dependencies": {
62
+ "@ant-design/icons": "^6.0.0",
63
+ "@types/js-cookie": "^3.0.6",
64
+ "antd": "^5.27.0",
65
+ "immer": "^10.1.1",
66
+ "js-cookie": "^3.0.5",
67
+ "zustand": "^5.0.8"
68
+ },
69
+ "devDependencies": {
70
+ "@eslint/eslintrc": "^3",
71
+ "@tailwindcss/postcss": "^4",
72
+ "@types/node": "^20",
73
+ "@types/react": "^19",
74
+ "@types/react-dom": "^19",
75
+ "eslint": "^9",
76
+ "eslint-config-next": "15.4.4",
77
+ "next": "15.4.4",
78
+ "prettier": "^3.6.2",
79
+ "react": "19.1.0",
80
+ "react-dom": "19.1.0",
81
+ "tailwindcss": "^4",
82
+ "tsup": "^8.5.1",
83
+ "typescript": "^5"
84
+ },
85
+ "keywords": [
86
+ "nextjs",
87
+ "authentication",
88
+ "auth",
89
+ "mailsentry",
90
+ "zustand",
91
+ "multi-step",
92
+ "cross-tab-sync",
93
+ "antd",
94
+ "typescript",
95
+ "react"
96
+ ],
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "https://github.com/danielaei/mailsentry-auth.git"
100
+ },
101
+ "author": "danielaei",
102
+ "license": "MIT"
103
+ }
@@ -0,0 +1,22 @@
1
+ 'use server';
2
+
3
+ import { cookies } from 'next/headers';
4
+
5
+ /**
6
+ * Server action to get authentication tokens from cookies
7
+ * This function runs on the server side and can access cookies directly
8
+ * Returns tokens directly for easy use in cookie-utils
9
+ */
10
+ export async function getAuthTokens(): Promise<{ accessToken: string | null; refreshToken: string | null }> {
11
+ try {
12
+ const cookieStore = await cookies();
13
+
14
+ const accessToken = cookieStore.get('auth_access_token')?.value || null;
15
+ const refreshToken = cookieStore.get('auth_refresh_token')?.value || null;
16
+
17
+ return { accessToken, refreshToken };
18
+ } catch (error) {
19
+ console.error('Error getting auth tokens from server:', error);
20
+ return { accessToken: null, refreshToken: null };
21
+ }
22
+ }
@@ -0,0 +1,3 @@
1
+ export {
2
+ getAuthTokens,
3
+ } from './auth-actions';