mbkauthe 1.3.4 → 1.4.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 +249 -187
- package/docs/api.md +841 -0
- package/docs/db.md +54 -31
- package/index.js +13 -2
- package/lib/main.js +106 -38
- package/lib/pool.js +14 -7
- package/lib/validateSessionAndRole.js +75 -83
- package/package.json +5 -5
- package/public/main.js +134 -0
- package/views/2fa.handlebars +35 -445
- package/views/Error/dError.handlebars +71 -551
- package/views/info.handlebars +180 -160
- package/views/loginmbkauthe.handlebars +37 -557
- package/views/sharedStyles.handlebars +498 -0
- package/views/showmessage.handlebars +97 -62
package/README.md
CHANGED
|
@@ -1,258 +1,320 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
[
|
|
26
|
-
- [License](#license)
|
|
27
|
-
- [Contact \& Support](#contact--support)
|
|
28
|
-
|
|
29
|
-
`mbkAuthe` is a reusable authentication system for Node.js applications, designed to simplify session management, user authentication, and role-based access control. It integrates seamlessly with PostgreSQL and supports features like Two-Factor Authentication (2FA) and session restoration.
|
|
30
|
-
|
|
31
|
-
## Features
|
|
32
|
-
|
|
33
|
-
- **Session Management:** Simplifies session handling with secure session restoration and expiration mechanisms.
|
|
34
|
-
- **User Authentication:** Provides robust authentication, including support for username/password and Two-Factor Authentication (2FA).
|
|
35
|
-
- **Role-Based Access Control (RBAC):** Enables fine-grained access control by validating user roles and permissions.
|
|
36
|
-
- **Integration with PostgreSQL:** Seamlessly integrates with PostgreSQL for user and session data storage.
|
|
37
|
-
- **Middleware Functions:** Includes reusable middleware for session validation, role checking, and user authentication.
|
|
38
|
-
- **API Endpoints:** Offers a set of RESTful APIs for login, logout, session termination, and package information retrieval.
|
|
39
|
-
- **Environment Configuration:** Supports flexible configuration through .env files for deployment-specific settings.
|
|
40
|
-
- **Demo Account:** Provides a demo account for hands-on exploration of the authentication system.
|
|
41
|
-
- **Database Schema:** Predefined database structure for user, session, and 2FA data management.
|
|
42
|
-
- **Extensibility:** Designed to be easily integrated into existing Node.js applications.
|
|
43
|
-
- **Secure Cookies:** Ensures secure session handling with cookie expiration and domain-specific settings
|
|
44
|
-
|
|
45
|
-
## Installation
|
|
46
|
-
|
|
47
|
-
Install the package via npm:
|
|
1
|
+
# MBKAuthe - Authentication System for Node.js
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/mbkauthe)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](https://github.com/MIbnEKhalid/mbkauthe/actions/workflows/publish.yml)
|
|
7
|
+
[](https://github.com/MIbnEKhalid/mbkauthe/actions/workflows/codeql.yml)
|
|
8
|
+
|
|
9
|
+
**MBKAuth** is a reusable, production-ready authentication system for Node.js applications built by MBKTechStudio. It provides secure session management, two-factor authentication (2FA), role-based access control, and multi-application support out of the box.
|
|
10
|
+
|
|
11
|
+
## ✨ Features
|
|
12
|
+
|
|
13
|
+
- 🔐 **Secure Authentication** - Password hashing with bcrypt
|
|
14
|
+
- 🔑 **Session Management** - PostgreSQL-backed session storage
|
|
15
|
+
- 📱 **Two-Factor Authentication (2FA)** - Optional TOTP-based 2FA with speakeasy
|
|
16
|
+
- 👥 **Role-Based Access Control** - SuperAdmin, NormalUser, and Guest roles
|
|
17
|
+
- 🎯 **Multi-Application Support** - Control user access across multiple apps
|
|
18
|
+
- 🛡️ **Security Features** - CSRF protection, rate limiting, secure cookies
|
|
19
|
+
- 🌐 **Subdomain Session Sharing** - Sessions work across all subdomains
|
|
20
|
+
- 🚀 **Easy Integration** - Drop-in authentication for Express.js apps
|
|
21
|
+
- 📊 **Database-Driven** - PostgreSQL for user and session management
|
|
22
|
+
- 🎨 **Customizable Views** - Handlebars templates for login/2FA pages
|
|
23
|
+
|
|
24
|
+
## 📦 Installation
|
|
48
25
|
|
|
49
26
|
```bash
|
|
50
27
|
npm install mbkauthe
|
|
51
28
|
```
|
|
52
29
|
|
|
53
|
-
##
|
|
30
|
+
## 🚀 Quick Start
|
|
31
|
+
|
|
32
|
+
### 1. Set Up Environment Variables
|
|
33
|
+
|
|
34
|
+
Create a `.env` file in your project root:
|
|
35
|
+
|
|
36
|
+
```env
|
|
37
|
+
# Application Configuration
|
|
38
|
+
APP_NAME=your-app-name
|
|
39
|
+
SESSION_SECRET_KEY=your-secure-random-secret-key
|
|
40
|
+
IS_DEPLOYED=false
|
|
41
|
+
DOMAIN=localhost
|
|
42
|
+
|
|
43
|
+
# Database Configuration
|
|
44
|
+
LOGIN_DB=postgresql://username:password@localhost:5432/database_name
|
|
45
|
+
|
|
46
|
+
# Optional Features
|
|
47
|
+
MBKAUTH_TWO_FA_ENABLE=false
|
|
48
|
+
COOKIE_EXPIRE_TIME=2
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For detailed environment configuration, see [Environment Configuration Guide](env.md).
|
|
52
|
+
|
|
53
|
+
### 2. Set Up Database
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Create the required tables in your PostgreSQL database. See [Database Structure Documentation](docs/db.md) for complete schemas.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
```sql
|
|
58
|
+
-- Users table
|
|
59
|
+
CREATE TYPE role AS ENUM ('SuperAdmin', 'NormalUser', 'Guest');
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
CREATE TABLE "Users" (
|
|
62
|
+
id SERIAL PRIMARY KEY,
|
|
63
|
+
"UserName" VARCHAR(50) NOT NULL UNIQUE,
|
|
64
|
+
"Password" VARCHAR(61) NOT NULL,
|
|
65
|
+
"Role" role DEFAULT 'NormalUser' NOT NULL,
|
|
66
|
+
"Active" BOOLEAN DEFAULT FALSE,
|
|
67
|
+
"AllowedApps" JSONB DEFAULT '["mbkauthe"]',
|
|
68
|
+
"SessionId" VARCHAR(213),
|
|
69
|
+
"created_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
70
|
+
);
|
|
60
71
|
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
-- Session table (created automatically by connect-pg-simple)
|
|
73
|
+
-- TwoFA table (optional, if 2FA is enabled)
|
|
74
|
+
```
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
### 3. Integrate with Your Express App
|
|
65
77
|
|
|
66
|
-
### Basic Setup
|
|
67
|
-
1. Import and configure the router in your Express application:
|
|
68
78
|
```javascript
|
|
69
|
-
import express from
|
|
70
|
-
import
|
|
79
|
+
import express from 'express';
|
|
80
|
+
import mbkauthe from 'mbkauthe';
|
|
81
|
+
import { validateSession, checkRolePermission } from 'mbkauthe';
|
|
82
|
+
import dotenv from 'dotenv';
|
|
83
|
+
|
|
84
|
+
dotenv.config();
|
|
85
|
+
|
|
86
|
+
// Set mbkauthe configuration
|
|
87
|
+
process.env.mbkautheVar = JSON.stringify({
|
|
88
|
+
APP_NAME: process.env.APP_NAME,
|
|
89
|
+
SESSION_SECRET_KEY: process.env.SESSION_SECRET_KEY,
|
|
90
|
+
IS_DEPLOYED: process.env.IS_DEPLOYED,
|
|
91
|
+
DOMAIN: process.env.DOMAIN,
|
|
92
|
+
LOGIN_DB: process.env.LOGIN_DB,
|
|
93
|
+
MBKAUTH_TWO_FA_ENABLE: process.env.MBKAUTH_TWO_FA_ENABLE,
|
|
94
|
+
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 2,
|
|
95
|
+
loginRedirectURL: '/dashboard' // Redirect after successful login
|
|
96
|
+
});
|
|
71
97
|
|
|
72
98
|
const app = express();
|
|
73
99
|
|
|
74
|
-
|
|
100
|
+
// Mount MBKAuth routes
|
|
101
|
+
app.use(mbkauthe);
|
|
102
|
+
|
|
103
|
+
// Protected route example
|
|
104
|
+
app.get('/dashboard', validateSession, (req, res) => {
|
|
105
|
+
res.send(`Welcome ${req.session.user.username}!`);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Role-based route protection
|
|
109
|
+
app.get('/admin', validateSession, checkRolePermission(['SuperAdmin']), (req, res) => {
|
|
110
|
+
res.send('Admin panel');
|
|
111
|
+
});
|
|
75
112
|
|
|
76
113
|
app.listen(3000, () => {
|
|
77
|
-
|
|
114
|
+
console.log('Server running on http://localhost:3000');
|
|
78
115
|
});
|
|
79
116
|
```
|
|
80
|
-
2. Ensure your `.env` file is properly configured. Refer to the [Configuration Guide(env.md)](env.md) for details.
|
|
81
|
-
|
|
82
|
-
Example `.env` file:
|
|
83
|
-
```code
|
|
84
|
-
mbkautheVar='{
|
|
85
|
-
"APP_NAME": "MBKAUTH",
|
|
86
|
-
"SESSION_SECRET_KEY": "your-session-secret-key",
|
|
87
|
-
"IS_DEPLOYED": "true",
|
|
88
|
-
"LOGIN_DB": "postgres://username:password@host:port/database",
|
|
89
|
-
"MBKAUTH_TWO_FA_ENABLE": "false",
|
|
90
|
-
"COOKIE_EXPIRE_TIME": 2,
|
|
91
|
-
"DOMAIN": "yourdomain.com",
|
|
92
|
-
"loginRedirectURL": "/admin"
|
|
93
|
-
}'
|
|
94
|
-
```
|
|
95
117
|
|
|
96
|
-
##
|
|
118
|
+
## 🔧 API Reference
|
|
97
119
|
|
|
98
|
-
###
|
|
99
|
-
Validates the user's session to ensure it is active and not expired.
|
|
120
|
+
### Middleware Functions
|
|
100
121
|
|
|
101
|
-
|
|
102
|
-
|
|
122
|
+
#### `validateSession`
|
|
123
|
+
Validates that a user has an active session. Redirects to login if not authenticated.
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
// Require vaild session or to be login to access this page
|
|
110
|
-
router.get(["/home"], validateSession, (req, res) => {
|
|
111
|
-
// Restricted Code
|
|
125
|
+
```javascript
|
|
126
|
+
app.get('/protected', validateSession, (req, res) => {
|
|
127
|
+
// User is authenticated
|
|
128
|
+
console.log(req.session.user); // { id, username, role, sessionId }
|
|
112
129
|
});
|
|
113
130
|
```
|
|
114
131
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
### `checkRolePermission(userRole, requiredRoles)`
|
|
118
|
-
Checks if the user has the required role permissions.
|
|
132
|
+
#### `checkRolePermission(allowedRoles)`
|
|
133
|
+
Checks if the authenticated user has one of the allowed roles.
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
135
|
+
```javascript
|
|
136
|
+
app.get('/admin', validateSession, checkRolePermission(['SuperAdmin']), (req, res) => {
|
|
137
|
+
// Only SuperAdmin can access
|
|
138
|
+
});
|
|
139
|
+
```
|
|
123
140
|
|
|
124
|
-
|
|
125
|
-
|
|
141
|
+
#### `validateSessionAndRole(allowedRoles)`
|
|
142
|
+
Combined middleware for session validation and role checking.
|
|
126
143
|
|
|
127
|
-
|
|
144
|
+
```javascript
|
|
145
|
+
app.get('/moderator', validateSessionAndRole(['SuperAdmin', 'NormalUser']), (req, res) => {
|
|
146
|
+
// SuperAdmin or NormalUser can access
|
|
147
|
+
});
|
|
128
148
|
```
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
149
|
+
|
|
150
|
+
#### `authenticate(token)`
|
|
151
|
+
API authentication middleware using a secret token.
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
app.post('/api/data', authenticate(process.env.API_TOKEN), (req, res) => {
|
|
155
|
+
// Authenticated API request
|
|
132
156
|
});
|
|
133
157
|
```
|
|
134
|
-
---
|
|
135
158
|
|
|
136
|
-
###
|
|
137
|
-
Validates both the session and the user's role permissions.
|
|
159
|
+
### Routes Provided
|
|
138
160
|
|
|
139
|
-
|
|
140
|
-
- `session` (Object): The session object to validate.
|
|
141
|
-
- `userRole` (string): The role of the user.
|
|
142
|
-
- `requiredRoles` (optional) (string[]): An array of roles that are allowed access.
|
|
161
|
+
MBKAuth automatically adds these routes to your app:
|
|
143
162
|
|
|
144
|
-
-
|
|
145
|
-
|
|
163
|
+
- `GET /mbkauthe/login` - Login page
|
|
164
|
+
- `POST /mbkauthe/api/login` - Login endpoint
|
|
165
|
+
- `POST /mbkauthe/api/logout` - Logout endpoint
|
|
166
|
+
- `GET /mbkauthe/2fa` - Two-factor authentication page (if enabled)
|
|
167
|
+
- `POST /mbkauthe/api/verify-2fa` - 2FA verification endpoint
|
|
168
|
+
- `GET /mbkauthe/info` - MBKAuth version and configuration info
|
|
169
|
+
- `POST /mbkauthe/api/terminateAllSessions` - Terminate all active sessions (authenticated)
|
|
146
170
|
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
// Require vaild session or to be login to access this page
|
|
150
|
-
router.get(["/admin"], validateSessionAndRole("SuperAdmin"), (req, res) => {
|
|
151
|
-
// Restricted Code
|
|
152
|
-
});
|
|
153
|
-
```
|
|
154
|
-
---
|
|
171
|
+
## 🔐 Security Features
|
|
155
172
|
|
|
156
|
-
###
|
|
157
|
-
|
|
173
|
+
### Rate Limiting
|
|
174
|
+
- **Login attempts**: 8 attempts per minute
|
|
175
|
+
- **Logout attempts**: 10 attempts per minute
|
|
176
|
+
- **2FA attempts**: 5 attempts per minute
|
|
158
177
|
|
|
159
|
-
|
|
160
|
-
|
|
178
|
+
### CSRF Protection
|
|
179
|
+
All POST routes are protected with CSRF tokens. CSRF tokens are automatically included in rendered forms.
|
|
161
180
|
|
|
162
|
-
|
|
163
|
-
|
|
181
|
+
### Password Hashing
|
|
182
|
+
Passwords are hashed using bcrypt with a secure salt. Set `EncryptedPassword: "true"` in `mbkautheVar` to enable.
|
|
164
183
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
### Secure Cookies
|
|
185
|
+
- `httpOnly` flag prevents XSS attacks
|
|
186
|
+
- `sameSite: 'lax'` prevents CSRF attacks
|
|
187
|
+
- `secure` flag in production ensures HTTPS-only cookies
|
|
188
|
+
- Configurable expiration time
|
|
189
|
+
|
|
190
|
+
### Session Management
|
|
191
|
+
- PostgreSQL-backed persistent sessions
|
|
192
|
+
- Automatic session cleanup
|
|
193
|
+
- Session restoration from cookies
|
|
194
|
+
- Cross-subdomain session sharing (when deployed)
|
|
172
195
|
|
|
196
|
+
## 📱 Two-Factor Authentication
|
|
173
197
|
|
|
198
|
+
Enable 2FA by setting `MBKAUTH_TWO_FA_ENABLE=true` in your environment:
|
|
174
199
|
|
|
175
|
-
|
|
200
|
+
1. User logs in with username/password
|
|
201
|
+
2. If 2FA is enabled for the user, they're prompted for a 6-digit code
|
|
202
|
+
3. Code is verified using TOTP (Time-based One-Time Password)
|
|
203
|
+
4. Session is established after successful 2FA
|
|
176
204
|
|
|
177
|
-
###
|
|
205
|
+
### Database Setup for 2FA
|
|
178
206
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
207
|
+
```sql
|
|
208
|
+
CREATE TABLE "TwoFA" (
|
|
209
|
+
"UserName" VARCHAR(50) PRIMARY KEY REFERENCES "Users"("UserName"),
|
|
210
|
+
"TwoFAStatus" BOOLEAN NOT NULL,
|
|
211
|
+
"TwoFASecret" TEXT
|
|
212
|
+
);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## 🎨 Customization
|
|
184
216
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
- `400`: Missing or invalid input.
|
|
188
|
-
- `401`: Unauthorized (e.g., invalid credentials or 2FA token).
|
|
189
|
-
- `500`: Internal server error.
|
|
217
|
+
### Custom Login Redirect
|
|
218
|
+
Set `loginRedirectURL` in `mbkautheVar`:
|
|
190
219
|
|
|
191
|
-
|
|
220
|
+
```javascript
|
|
221
|
+
process.env.mbkautheVar = JSON.stringify({
|
|
222
|
+
// ... other config
|
|
223
|
+
loginRedirectURL: '/dashboard' // Redirect after login
|
|
224
|
+
});
|
|
225
|
+
```
|
|
192
226
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
227
|
+
### Custom Views
|
|
228
|
+
Override default views by creating files in your project's `views` directory:
|
|
229
|
+
- `views/loginmbkauthe.handlebars` - Login page
|
|
230
|
+
- `views/2fa.handlebars` - 2FA page
|
|
231
|
+
- `views/Error/dError.handlebars` - Error page
|
|
198
232
|
|
|
199
|
-
###
|
|
233
|
+
### Database Pool Access
|
|
234
|
+
Access the database pool for custom queries:
|
|
200
235
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- Response:
|
|
204
|
-
- `200`: All sessions terminated successfully.
|
|
205
|
-
- `500`: Internal server error.
|
|
236
|
+
```javascript
|
|
237
|
+
import { dblogin } from 'mbkauthe';
|
|
206
238
|
|
|
207
|
-
|
|
239
|
+
const result = await dblogin.query('SELECT * FROM "Users" WHERE "UserName" = $1', [username]);
|
|
240
|
+
```
|
|
208
241
|
|
|
209
|
-
|
|
242
|
+
## 🚢 Deployment
|
|
243
|
+
|
|
244
|
+
### Vercel Deployment
|
|
245
|
+
|
|
246
|
+
Add `vercel.json`:
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"version": 2,
|
|
251
|
+
"builds": [
|
|
252
|
+
{
|
|
253
|
+
"src": "index.js",
|
|
254
|
+
"use": "@vercel/node"
|
|
255
|
+
}
|
|
256
|
+
],
|
|
257
|
+
"routes": [
|
|
258
|
+
{
|
|
259
|
+
"src": "/(.*)",
|
|
260
|
+
"dest": "/index.js"
|
|
261
|
+
}
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
```
|
|
210
265
|
|
|
211
|
-
|
|
212
|
-
- **Response**:
|
|
213
|
-
- `200`: Successfully retrieved the `package.json` file.
|
|
214
|
-
- **Body**: JSON object containing the contents of the `package.json` file.
|
|
215
|
-
- `500`: Internal server error.
|
|
266
|
+
### Production Checklist
|
|
216
267
|
|
|
268
|
+
- [ ] Set `IS_DEPLOYED=true`
|
|
269
|
+
- [ ] Use a strong `SESSION_SECRET_KEY`
|
|
270
|
+
- [ ] Enable HTTPS
|
|
271
|
+
- [ ] Set correct `DOMAIN`
|
|
272
|
+
- [ ] Enable 2FA for sensitive applications
|
|
273
|
+
- [ ] Use environment variables for secrets
|
|
274
|
+
- [ ] Set appropriate `COOKIE_EXPIRE_TIME`
|
|
275
|
+
- [ ] Configure PostgreSQL with proper security
|
|
276
|
+
- [ ] Enable password hashing with bcrypt
|
|
217
277
|
|
|
218
|
-
|
|
278
|
+
## 📚 Documentation
|
|
219
279
|
|
|
220
|
-
|
|
280
|
+
- [API Documentation](docs/api.md) - Complete API reference and examples
|
|
281
|
+
- [Environment Configuration Guide](env.md) - Environment variables and setup
|
|
282
|
+
- [Database Structure](docs/db.md) - Database schemas and tables
|
|
221
283
|
|
|
222
|
-
|
|
223
|
-
- **Response**:
|
|
224
|
-
- `200`: Successfully retrieved the version information.
|
|
225
|
-
- **Body**: JSON object containing the version, e.g., `{ "version": "1.0.0" }`.
|
|
226
|
-
- `500`: Internal server error.
|
|
284
|
+
## 🔄 Version Check
|
|
227
285
|
|
|
286
|
+
MBKAuth automatically checks for updates on startup and warns if a newer version is available. Keep your package updated for security patches.
|
|
228
287
|
|
|
229
|
-
|
|
288
|
+
## 🤝 Contributing
|
|
230
289
|
|
|
231
|
-
|
|
290
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
232
291
|
|
|
233
|
-
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
292
|
+
1. Fork the repository
|
|
293
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
294
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
295
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
296
|
+
5. Open a Pull Request
|
|
238
297
|
|
|
239
|
-
##
|
|
298
|
+
## 📝 License
|
|
240
299
|
|
|
241
|
-
This project
|
|
300
|
+
This project is licensed under the Mozilla Public License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
242
301
|
|
|
243
|
-
|
|
244
|
-
2. **sess**: Contains session-related data for users.
|
|
245
|
-
3. **TwoFA**: Saves the Two-Factor Authentication (2FA) secrets for users.
|
|
302
|
+
## 👨💻 Author
|
|
246
303
|
|
|
247
|
-
|
|
304
|
+
**Muhammad Bin Khalid**
|
|
305
|
+
Email: [support@mbktechstudio.com](support@mbktechstudio.com) or [chmuhammadbinkhalid28@gmail.com](mailto:chmuhammadbinkhalid28@gmail.com)
|
|
306
|
+
GitHub: [@MIbnEKhalid](https://github.com/MIbnEKhalid)
|
|
248
307
|
|
|
249
|
-
##
|
|
250
|
-
This project is licensed under the `Mozilla Public License 2.0`. See the [LICENSE](./LICENSE) file for details.
|
|
308
|
+
## 🐛 Issues & Support
|
|
251
309
|
|
|
310
|
+
Found a bug or need help? Please [open an issue](https://github.com/MIbnEKhalid/mbkauthe/issues) on GitHub.
|
|
252
311
|
|
|
312
|
+
## 🔗 Links
|
|
253
313
|
|
|
254
|
-
|
|
314
|
+
- [npm Package](https://www.npmjs.com/package/mbkauthe)
|
|
315
|
+
- [GitHub Repository](https://github.com/MIbnEKhalid/mbkauthe)
|
|
316
|
+
- [MBKTechStudio](https://mbktechstudio.com)
|
|
255
317
|
|
|
256
|
-
|
|
318
|
+
---
|
|
257
319
|
|
|
258
|
-
|
|
320
|
+
Made with ❤️ by [MBKTechStudio](https://mbktechstudio.com)
|