@tern-secure/backend 1.0.1 → 1.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.
@@ -1,12 +1,12 @@
1
1
 
2
- > @tern-secure/backend@1.0.1 build /home/runner/work/typescript/typescript/packages/backend
2
+ > @tern-secure/backend@1.1.0 build /home/runner/work/typescript/typescript/packages/backend
3
3
  > pnpm clean && tsup && tsc -p tsconfig.add.json
4
4
 
5
5
 
6
- > @tern-secure/backend@1.0.1 clean /home/runner/work/typescript/typescript/packages/backend
6
+ > @tern-secure/backend@1.1.0 clean /home/runner/work/typescript/typescript/packages/backend
7
7
  > rimraf dist
8
8
 
9
- CLI Building entry: src/index.ts, src/ternsecureauth.ts, src/utils/admin-init.ts, src/utils/config.ts, src/admin/sessionTernSecure.ts, src/admin/tenant.ts
9
+ CLI Building entry: src/index.ts, src/ternsecureauth.ts, src/admin/sessionTernSecure.ts, src/admin/tenant.ts, src/utils/admin-init.ts, src/utils/config.ts
10
10
  CLI Using tsconfig: tsconfig.json
11
11
  CLI tsup v8.5.0
12
12
  CLI Using tsup config: /home/runner/work/typescript/typescript/packages/backend/tsup.config.ts
@@ -20,29 +20,29 @@
20
20
  ESM Build start
21
21
  CLI Cleaning output folder
22
22
  CJS Build start
23
- ESM dist/esm/utils/admin-init.js 688.00 B
23
+ ESM dist/esm/admin/sessionTernSecure.js 6.87 KB
24
24
  ESM dist/esm/index.js 593.00 B
25
- ESM dist/esm/admin/sessionTernSecure.js 3.92 KB
25
+ ESM dist/esm/utils/admin-init.js 688.00 B
26
26
  ESM dist/esm/ternsecureauth.js 407.00 B
27
- ESM dist/esm/utils/config.js 2.26 KB
28
27
  ESM dist/esm/admin/tenant.js 1.19 KB
29
- ESM dist/esm/utils/admin-init.js.map 1.32 KB
28
+ ESM dist/esm/utils/config.js 2.26 KB
29
+ ESM dist/esm/admin/sessionTernSecure.js.map 13.36 KB
30
30
  ESM dist/esm/index.js.map 593.00 B
31
- ESM dist/esm/admin/sessionTernSecure.js.map 8.29 KB
31
+ ESM dist/esm/utils/admin-init.js.map 1.32 KB
32
+ ESM dist/esm/admin/tenant.js.map 2.42 KB
32
33
  ESM dist/esm/ternsecureauth.js.map 842.00 B
33
34
  ESM dist/esm/utils/config.js.map 5.25 KB
34
- ESM dist/esm/admin/tenant.js.map 2.42 KB
35
- ESM ⚡️ Build success in 32ms
35
+ ESM ⚡️ Build success in 34ms
36
36
  CJS dist/cjs/index.js 2.01 KB
37
- CJS dist/cjs/admin/sessionTernSecure.js 5.54 KB
38
- CJS dist/cjs/utils/admin-init.js 2.55 KB
39
- CJS dist/cjs/ternsecureauth.js 1.43 KB
40
37
  CJS dist/cjs/admin/tenant.js 2.25 KB
41
38
  CJS dist/cjs/utils/config.js 3.48 KB
39
+ CJS dist/cjs/utils/admin-init.js 2.55 KB
40
+ CJS dist/cjs/ternsecureauth.js 1.43 KB
41
+ CJS dist/cjs/admin/sessionTernSecure.js 8.57 KB
42
+ CJS dist/cjs/admin/tenant.js.map 2.46 KB
43
+ CJS dist/cjs/utils/config.js.map 5.32 KB
42
44
  CJS dist/cjs/index.js.map 593.00 B
43
- CJS dist/cjs/admin/sessionTernSecure.js.map 8.42 KB
44
45
  CJS dist/cjs/utils/admin-init.js.map 1.42 KB
45
46
  CJS dist/cjs/ternsecureauth.js.map 885.00 B
46
- CJS dist/cjs/admin/tenant.js.map 2.46 KB
47
- CJS dist/cjs/utils/config.js.map 5.32 KB
48
- CJS ⚡️ Build success in 32ms
47
+ CJS dist/cjs/admin/sessionTernSecure.js.map 13.49 KB
48
+ CJS ⚡️ Build success in 34ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @tern-secure/backend
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5f29862: advanced Auth cookies and session management
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [5f29862]
12
+ - @tern-secure/types@1.0.2
13
+
3
14
  ## 1.0.1
4
15
 
5
16
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tern-secure/backend",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/TernSecure/typescript.git",
@@ -18,15 +18,13 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "tslib": "2.4.1",
21
- "@tern-secure/types": "1.0.1"
21
+ "@tern-secure/types": "1.0.2"
22
22
  },
23
23
  "devDependencies": {
24
+ "firebase-admin": "^12.7.0",
24
25
  "jose": "^5.0.0",
25
26
  "next": "15.3.2"
26
27
  },
27
- "peerDependencies": {
28
- "firebase-admin": "^12.0.0"
29
- },
30
28
  "engines": {
31
29
  "node": ">=20"
32
30
  },
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { cookies } from 'next/headers';
4
4
  import { adminTernSecureAuth as adminAuth } from '../utils/admin-init';
5
- import { handleFirebaseAuthError, type AuthErrorResponse } from '@tern-secure/types';
5
+ import { handleFirebaseAuthError, type AuthErrorResponse, type SessionParams, type SessionResult } from '@tern-secure/types';
6
6
 
7
7
  interface FirebaseAuthError extends Error {
8
8
  code?: string;
@@ -25,21 +25,128 @@ interface TernVerificationResult extends User {
25
25
  error?: AuthErrorResponse
26
26
  }
27
27
 
28
- export async function createSessionCookie(idToken: string) {
28
+
29
+ // DRY Constants
30
+ const SESSION_CONSTANTS = {
31
+ COOKIE_NAME: '_session_cookie',
32
+ DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1000, // 5 days
33
+ DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5,
34
+ } as const;
35
+
36
+ const COOKIE_OPTIONS = {
37
+ httpOnly: true,
38
+ secure: process.env.NODE_ENV === 'production',
39
+ sameSite: 'strict' as const,
40
+ path: '/',
41
+ } as const;
42
+
43
+
44
+
45
+ export async function createSessionCookie(params: SessionParams | string): Promise<SessionResult> {
29
46
  try {
30
- const expiresIn = 60 * 60 * 24 * 5 * 1000;
31
- const sessionCookie = await adminAuth.createSessionCookie(idToken, { expiresIn });
47
+ // Handle both old string format and new object format for backward compatibility
48
+ const idToken = typeof params === 'string' ? params : params.idToken;
49
+
50
+ if (!idToken) {
51
+ const error = new Error('ID token is required for session creation');
52
+ console.error('[createSessionCookie] Missing ID token:', error);
53
+ return {
54
+ success: false,
55
+ message: 'ID token is required',
56
+ error: 'INVALID_TOKEN',
57
+ cookieSet: false
58
+ };
59
+ }
60
+
61
+ // Verify the ID token first
62
+ let decodedToken;
63
+ try {
64
+ decodedToken = await adminAuth.verifyIdToken(idToken);
65
+ } catch (verifyError) {
66
+ console.error('[createSessionCookie] ID token verification failed:', verifyError);
67
+ const authError = handleFirebaseAuthError(verifyError);
68
+ return {
69
+ success: false,
70
+ message: authError.message,
71
+ error: authError.code,
72
+ cookieSet: false
73
+ };
74
+ }
75
+
76
+ if (!decodedToken) {
77
+ const error = new Error('Invalid ID token - verification returned null');
78
+ console.error('[createSessionCookie] Token verification returned null:', error);
79
+ return {
80
+ success: false,
81
+ message: 'Invalid ID token',
82
+ error: 'INVALID_TOKEN',
83
+ cookieSet: false
84
+ };
85
+ }
32
86
 
87
+ // Create session cookie
88
+ let sessionCookie;
89
+ try {
90
+ sessionCookie = await adminAuth.createSessionCookie(idToken, {
91
+ expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_MS
92
+ });
93
+ } catch (sessionError) {
94
+ console.error('[createSessionCookie] Firebase session cookie creation failed:', sessionError);
95
+ const authError = handleFirebaseAuthError(sessionError);
96
+ return {
97
+ success: false,
98
+ message: authError.message,
99
+ error: authError.code,
100
+ cookieSet: false
101
+ };
102
+ }
103
+
104
+ // Set the cookie and verify it was set
105
+ let cookieSetSuccessfully = false;
106
+ try {
33
107
  const cookieStore = await cookies();
34
- cookieStore.set('_session_cookie', sessionCookie, {
35
- maxAge: expiresIn,
36
- httpOnly: true,
37
- secure: process.env.NODE_ENV === 'production',
38
- path: '/',
108
+ cookieStore.set(SESSION_CONSTANTS.COOKIE_NAME, sessionCookie, {
109
+ maxAge: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,
110
+ ...COOKIE_OPTIONS,
39
111
  });
40
- return { success: true, message: 'Session created' };
112
+
113
+ // Verify the cookie was actually set
114
+ const verifySetCookie = cookieStore.get(SESSION_CONSTANTS.COOKIE_NAME);
115
+ cookieSetSuccessfully = !!verifySetCookie?.value;
116
+
117
+ if (!cookieSetSuccessfully) {
118
+ const error = new Error('Session cookie was not set successfully');
119
+ console.error('[createSessionCookie] Cookie verification failed:', error);
120
+ throw error;
121
+ }
122
+
123
+ } catch (cookieError) {
124
+ console.error('[createSessionCookie] Failed to set session cookie:', cookieError);
125
+ return {
126
+ success: false,
127
+ message: 'Failed to set session cookie',
128
+ error: 'COOKIE_SET_FAILED',
129
+ cookieSet: false
130
+ };
131
+ }
132
+
133
+ console.log(`[createSessionCookie] Session cookie created successfully for user: ${decodedToken.uid}`);
134
+ return {
135
+ success: true,
136
+ message: 'Session created successfully',
137
+ expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,
138
+ cookieSet: cookieSetSuccessfully
139
+ };
140
+
41
141
  } catch (error) {
42
- return { success: false, message: 'Failed to create session' };
142
+ console.error('[createSessionCookie] Unexpected error:', error);
143
+ const authError = handleFirebaseAuthError(error);
144
+ return {
145
+ success: false,
146
+ message: authError.message || 'Failed to create session',
147
+ error: authError.code || 'INTERNAL_ERROR',
148
+ cookieSet: false
149
+ };
43
150
  }
44
151
  }
45
152