my-ssap 1.0.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.
package/README.md ADDED
@@ -0,0 +1,269 @@
1
+ A lightweight, zero-dependency utility package for simple personal full-stack projects. It provides a clean API to manage Express server-side sessions and React frontend protected routes without complex configurations.
2
+
3
+ ## Installation
4
+
5
+ Ensure you have your peer dependencies installed in your projects:
6
+
7
+ ```bash
8
+ npm install ssap
9
+ ```
10
+
11
+ ---
12
+
13
+ ## 🛠️ Backend Usage (Express)
14
+
15
+ Import server-side helpers from `ssap/backend`.
16
+
17
+ ```javascript
18
+ import express from 'express';
19
+ import { initSession, requireAuth } from 'ssap/backend';
20
+
21
+ const app = express();
22
+ app.use(express.json());
23
+
24
+ // 1. Initialize session middleware with a secret key
25
+ app.use(initSession('your-secure-dev-secret-key', false)); // Set second param to true in production (HTTPS)
26
+
27
+ // 2. Login Route (Set session details on successful authentication)
28
+ app.post('/api/login', (req, res) => {
29
+ const { username, password } = req.body;
30
+
31
+ // Validate credentials here...
32
+ if (username === 'admin' && password === 'password') {
33
+ req.session.userId = 1;
34
+ req.session.username = username;
35
+ return res.json({ authenticated: true, message: 'Logged in!' });
36
+ }
37
+
38
+ return res.status(401).json({ authenticated: false, error: 'Invalid credentials' });
39
+ });
40
+
41
+ // 3. Auth Check Route (Used by React to verify active sessions)
42
+ app.get('/api/auth-check', (req, res) => {
43
+ if (req.session && req.session.userId) {
44
+ return res.json({ authenticated: true, username: req.session.username });
45
+ }
46
+ return res.status(401).json({ authenticated: false });
47
+ });
48
+
49
+ // 4. Logout Route
50
+ app.post('/api/logout', (req, res) => {
51
+ req.session.destroy((err) => {
52
+ if (err) return res.status(500).json({ message: 'Could not log out' });
53
+ res.clearCookie('connect.sid');
54
+ return res.json({ authenticated: false });
55
+ });
56
+ });
57
+
58
+ // 5. Protect sensitive endpoints using the middleware
59
+ app.get('/api/dashboard-data', requireAuth, (req, res) => {
60
+ res.json({ message: 'Welcome to your private dashboard data!' });
61
+ });
62
+
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 💻 Frontend Usage (React + React Router)
68
+
69
+ Import frontend context and route wrappers from `ssap/frontend`.
70
+
71
+ ### 1. Setup Your App Routing (`App.jsx`)
72
+
73
+ Wrap your routing setup inside `AuthProvider` and secure internal routes using the `<ProtectedRoute />` component.
74
+
75
+ ```jsx
76
+ import React from 'react';
77
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
78
+ import { AuthProvider, ProtectedRoute } from 'ssap/frontend';
79
+
80
+ import Login from './pages/Login';
81
+ import Dashboard from './pages/Dashboard';
82
+
83
+ export default function App() {
84
+ return (
85
+ <AuthProvider authCheckUrl="/api/auth-check">
86
+ <BrowserRouter>
87
+ <Routes>
88
+ {/* Public Route */}
89
+ <Route path="/login" element={<Login />} />
90
+
91
+ {/* Protected Routes Block */}
92
+ <Route element={<ProtectedRoute redirectTo="/login" />}>
93
+ <Route path="/dashboard" element={<Dashboard />} />
94
+ </Route>
95
+ </Routes>
96
+ </BrowserRouter>
97
+ </AuthProvider>
98
+ );
99
+ }
100
+
101
+ ```
102
+
103
+ ### 2. Consuming Auth State in Components (`Dashboard.jsx`)
104
+
105
+ Use the `useAuth` hook to access the logged-in user details or display loading states while the initial check finishes.
106
+
107
+ ```jsx
108
+ import React from 'react';
109
+ import { useAuth } from 'ssap/frontend';
110
+
111
+ export default function Dashboard() {
112
+ const { user, loading } = useAuth();
113
+
114
+ if (loading) return <div>Checking auth state...</div>;
115
+
116
+ return (
117
+ <div>
118
+ <h1>Welcome, {user?.username}!</h1>
119
+ <p>This page is fully protected from unauthenticated guests.</p>
120
+ </div>
121
+ );
122
+ }
123
+
124
+ ```
125
+
126
+ ---
127
+
128
+ ## API Reference
129
+
130
+ ### Backend Exports (`ssap/backend`)
131
+
132
+ * `initSession(secretKey, isProduction)`: Configures cookie-backed express sessions. Disables `secure` flag on localhost when `isProduction` is false.
133
+ * `requireAuth(req, res, next)`: Express middleware that blocks incoming requests if `req.session.userId` is missing. Returns a `401 Unauthorized` response.
134
+
135
+ ### Frontend Exports (`ssap/frontend`)
136
+
137
+ * `<AuthProvider authCheckUrl="/api/auth-check">`: Handles checking current cookie status on boot. Caches context values globally.
138
+ * `useAuth()`: Access global hook context properties: `{ user, setUser, loading }`.
139
+ * `<ProtectedRoute redirectTo="/login" />`: Route-level element guarding children paths using `react-router-dom` standard `<Outlet />`.
140
+
141
+ ---
142
+
143
+ ## 🛠️ Backend Usage (Express)
144
+
145
+ Import server-side helpers from `ssap/backend`.
146
+
147
+ ```javascript
148
+ import express from 'express';
149
+ import { initSession, requireAuth } from 'ssap/backend';
150
+
151
+ const app = express();
152
+ app.use(express.json());
153
+
154
+ // 1. Initialize session middleware with a secret key
155
+ app.use(initSession('your-secure-dev-secret-key', false)); // Set second param to true in production (HTTPS)
156
+
157
+ // 2. Login Route (Set session details on successful authentication)
158
+ app.post('/api/login', (req, res) => {
159
+ const { username, password } = req.body;
160
+
161
+ // Validate credentials here...
162
+ if (username === 'admin' && password === 'password') {
163
+ req.session.userId = 1;
164
+ req.session.username = username;
165
+ return res.json({ authenticated: true, message: 'Logged in!' });
166
+ }
167
+
168
+ return res.status(401).json({ authenticated: false, error: 'Invalid credentials' });
169
+ });
170
+
171
+ // 3. Auth Check Route (Used by React to verify active sessions)
172
+ app.get('/api/auth-check', (req, res) => {
173
+ if (req.session && req.session.userId) {
174
+ return res.json({ authenticated: true, username: req.session.username });
175
+ }
176
+ return res.status(401).json({ authenticated: false });
177
+ });
178
+
179
+ // 4. Logout Route
180
+ app.post('/api/logout', (req, res) => {
181
+ req.session.destroy((err) => {
182
+ if (err) return res.status(500).json({ message: 'Could not log out' });
183
+ res.clearCookie('connect.sid');
184
+ return res.json({ authenticated: false });
185
+ });
186
+ });
187
+
188
+ // 5. Protect sensitive endpoints using the middleware
189
+ app.get('/api/dashboard-data', requireAuth, (req, res) => {
190
+ res.json({ message: 'Welcome to your private dashboard data!' });
191
+ });
192
+
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 💻 Frontend Usage (React + React Router)
198
+
199
+ Import frontend context and route wrappers from `ssap/frontend`.
200
+
201
+ ### 1. Setup Your App Routing (`App.jsx`)
202
+
203
+ Wrap your routing setup inside `AuthProvider` and secure internal routes using the `<ProtectedRoute />` component.
204
+
205
+ ```jsx
206
+ import React from 'react';
207
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
208
+ import { AuthProvider, ProtectedRoute } from 'ssap/frontend';
209
+
210
+ import Login from './pages/Login';
211
+ import Dashboard from './pages/Dashboard';
212
+
213
+ export default function App() {
214
+ return (
215
+ <AuthProvider authCheckUrl="/api/auth-check">
216
+ <BrowserRouter>
217
+ <Routes>
218
+ {/* Public Route */}
219
+ <Route path="/login" element={<Login />} />
220
+
221
+ {/* Protected Routes Block */}
222
+ <Route element={<ProtectedRoute redirectTo="/login" />}>
223
+ <Route path="/dashboard" element={<Dashboard />} />
224
+ </Route>
225
+ </Routes>
226
+ </BrowserRouter>
227
+ </AuthProvider>
228
+ );
229
+ }
230
+
231
+ ```
232
+
233
+ ### 2. Consuming Auth State in Components (`Dashboard.jsx`)
234
+
235
+ Use the `useAuth` hook to access the logged-in user details or display loading states while the initial check finishes.
236
+
237
+ ```jsx
238
+ import React from 'react';
239
+ import { useAuth } from 'ssap/frontend';
240
+
241
+ export default function Dashboard() {
242
+ const { user, loading } = useAuth();
243
+
244
+ if (loading) return <div>Checking auth state...</div>;
245
+
246
+ return (
247
+ <div>
248
+ <h1>Welcome, {user?.username}!</h1>
249
+ <p>This page is fully protected from unauthenticated guests.</p>
250
+ </div>
251
+ );
252
+ }
253
+
254
+ ```
255
+
256
+ ---
257
+
258
+ ## API Reference
259
+
260
+ ### Backend Exports (`ssap/backend`)
261
+
262
+ * `initSession(secretKey, isProduction)`: Configures cookie-backed express sessions. Disables `secure` flag on localhost when `isProduction` is false.
263
+ * `requireAuth(req, res, next)`: Express middleware that blocks incoming requests if `req.session.userId` is missing. Returns a `401 Unauthorized` response.
264
+
265
+ ### Frontend Exports (`ssap/frontend`)
266
+
267
+ * `<AuthProvider authCheckUrl="/api/auth-check">`: Handles checking current cookie status on boot. Caches context values globally.
268
+ * `useAuth()`: Access global hook context properties: `{ user, setUser, loading }`.
269
+ * `<ProtectedRoute redirectTo="/login" />`: Route-level element guarding children paths using `react-router-dom` standard `<Outlet />`.
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "my-ssap",
3
+ "version": "1.0.0",
4
+ "description": "A Simple Session-based Authentication Package",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "Rubayita",
11
+ "license": "ISC",
12
+ "type": "module",
13
+ "exports": {
14
+ "./backend": "./src/backend.js",
15
+ "./frontend": "./src/frontend.jsx"
16
+ },
17
+ "peerDependencies": {
18
+ "express-session": "^1.18.0",
19
+ "react": "^18.0.0 || ^19.0.0",
20
+ "react-router-dom": "^6.0.0 || ^7.0.0"
21
+ }
22
+ }
package/src/backend.js ADDED
@@ -0,0 +1,19 @@
1
+ import session from 'express-session';
2
+
3
+ export function initSession(secretKey) {
4
+ return session({
5
+ secret: secretKey,
6
+ resave: false,
7
+ saveUninitialized: false,
8
+ cookie:{
9
+ maxAge: 1000 * 60 * 60 * 24
10
+ }
11
+ })
12
+ }
13
+
14
+ export function requireAuth(req, res, next) {
15
+ if (req.session && req.session.userID){
16
+ return next();
17
+ }
18
+ return res.status(401).json({ authenticated: false, Error: 'Unauthenticated' })
19
+ }
@@ -0,0 +1,42 @@
1
+ import React from 'react'
2
+ import { Navigate, Outlet } from 'react-router-dom'
3
+
4
+ const AuthContext = React.createContext(null)
5
+
6
+ export function AuthProvider({ children, authCheckUrl = '/auth/auth-check' }){
7
+ const [ user, setUser ] = React.useState(null)
8
+ const [ loadiing, setLoading ] = React.useState(true)
9
+
10
+ React.useEffect(()=>{
11
+ fetch(authCheckUrl)
12
+ .then((res)=>res.json())
13
+ .then((data) => {
14
+ if (data.authenticated) {
15
+ setUser(data)
16
+ }
17
+ })
18
+ .catch(() => setUser(null))
19
+ .finally(() => setLoading(false))
20
+ }, [authCheckUrl])
21
+
22
+ return (
23
+ <AuthContext.Provider value={{ user, setUser, loading }}>
24
+ {children}
25
+ </AuthContext.Provider>
26
+ )
27
+ }
28
+
29
+ export function useAuth() {
30
+ return React.useContext(AuthContext)
31
+ }
32
+
33
+ export function ProtectedRoute({
34
+ redirectTo = '/login'
35
+ }){
36
+ const { user, loading } = useAuth();
37
+
38
+ if (loading) return <div>Loading authenticated...</div>
39
+ if (!user) return <Navigate to={redirectTo} replace />
40
+
41
+ return <Outlet />
42
+ }