@xcelsior/auth 0.1.1

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,22 @@
1
+
2
+ > @xcelsior/auth@0.1.1 build /Users/tuannguyen/Work/excelsior-packages/packages/services/auth
3
+ > tsup
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.0
8
+ CLI Using tsup config: /Users/tuannguyen/Work/excelsior-packages/packages/services/auth/tsup.config.ts
9
+ CLI Target: es2020
10
+ CLI Cleaning output folder
11
+ CJS Build start
12
+ ESM Build start
13
+ CJS dist/index.js 16.47 KB
14
+ CJS dist/index.js.map 30.61 KB
15
+ CJS ⚡️ Build success in 146ms
16
+ ESM dist/index.mjs 14.28 KB
17
+ ESM dist/index.mjs.map 30.43 KB
18
+ ESM ⚡️ Build success in 146ms
19
+ DTS Build start
20
+ DTS ⚡️ Build success in 3500ms
21
+ DTS dist/index.d.ts 3.71 KB
22
+ DTS dist/index.d.mts 3.71 KB
@@ -0,0 +1,5 @@
1
+
2
+ > @xcelsior/auth@0.1.0 lint /Users/tuannguyen/Work/excelsior-packages/packages/services/auth
3
+ > biome check .
4
+
5
+ Checked 21 files in 28ms. No fixes applied.
@@ -0,0 +1,12 @@
1
+
2
+ > @xcelsior/auth@0.1.0 test /Users/tuannguyen/Work/excelsior-packages/packages/services/auth
3
+ > jest --passWithNoTests
4
+
5
+ Determining test suites to run...No tests found, exiting with code 0
6
+ 
7
+
8
+ 
9
+ 
10
+
11
+ 
12
+ 
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @xcelsior/auth
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - initial auth package
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # @xcelsior/serverless-auth
2
+
3
+ A reusable serverless authentication package with role-based access control and configurable email notifications.
4
+
5
+ ## Features
6
+
7
+ - User authentication (signup, signin)
8
+ - Email verification
9
+ - Password reset flow
10
+ - Role-based access control (RBAC)
11
+ - Configurable email providers (SMTP, AWS SES)
12
+ - Multiple storage providers (DynamoDB, with MongoDB and PostgreSQL coming soon)
13
+ - JWT-based authentication
14
+ - Middleware for protecting routes
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @xcelsior/serverless-auth
20
+ # or
21
+ yarn add @xcelsior/serverless-auth
22
+ # or
23
+ pnpm add @xcelsior/serverless-auth
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ### Configuration
29
+
30
+ ```typescript
31
+ import { AuthService, AuthConfig } from '@xcelsior/serverless-auth';
32
+
33
+ const config: AuthConfig = {
34
+ jwt: {
35
+ secret: 'your-jwt-secret',
36
+ expiresIn: '1d',
37
+ },
38
+ // Storage configuration
39
+ storage: {
40
+ // DynamoDB configuration
41
+ type: 'dynamodb',
42
+ options: {
43
+ tableName: 'your-users-table',
44
+ region: 'us-east-1',
45
+ },
46
+ // Or MongoDB configuration (coming soon)
47
+ // type: 'mongodb',
48
+ // options: {
49
+ // uri: 'mongodb://localhost:27017',
50
+ // dbName: 'auth',
51
+ // collectionName: 'users',
52
+ // },
53
+ // Or PostgreSQL configuration (coming soon)
54
+ // type: 'postgres',
55
+ // options: {
56
+ // connectionString: 'postgresql://user:pass@localhost:5432/db',
57
+ // schema: 'public',
58
+ // tableName: 'users',
59
+ // },
60
+ },
61
+ // Email configuration
62
+ email: {
63
+ // SMTP configuration
64
+ type: 'smtp',
65
+ from: 'noreply@yourdomain.com',
66
+ options: {
67
+ host: 'smtp.provider.com',
68
+ port: 587,
69
+ secure: false,
70
+ auth: {
71
+ user: 'your-smtp-username',
72
+ pass: 'your-smtp-password',
73
+ },
74
+ },
75
+ // Or AWS SES configuration
76
+ // type: 'ses',
77
+ // from: 'noreply@yourdomain.com',
78
+ // options: {
79
+ // region: 'us-east-1',
80
+ // credentials: {
81
+ // accessKeyId: 'your-access-key',
82
+ // secretAccessKey: 'your-secret-key',
83
+ // },
84
+ // sourceArn: 'arn:aws:ses:region:account-id:identity/yourdomain.com', // Optional: ARN of the verified identity
85
+ // },
86
+ // Optional: Custom email templates (defaults will be used if not provided)
87
+ templates: {
88
+ verification: {
89
+ subject: 'Verify your email',
90
+ html: (token) => `
91
+ <h1>Verify your email</h1>
92
+ <p>Click the link below to verify your email:</p>
93
+ <a href="https://yourdomain.com/verify-email?token=${token}">Verify Email</a>
94
+ `,
95
+ },
96
+ resetPassword: {
97
+ subject: 'Reset your password',
98
+ html: (token) => `
99
+ <h1>Reset your password</h1>
100
+ <p>Click the link below to reset your password:</p>
101
+ <a href="https://yourdomain.com/reset-password?token=${token}">Reset Password</a>
102
+ `,
103
+ },
104
+ },
105
+ },
106
+ };
107
+
108
+ const authService = new AuthService(config);
109
+ ```
110
+
111
+ ### Authentication
112
+
113
+ ```typescript
114
+ // Signup
115
+ const { user, token } = await authService.signup('user@example.com', 'password');
116
+
117
+ // Signin
118
+ const { user, token } = await authService.signin('user@example.com', 'password');
119
+
120
+ // Verify email
121
+ await authService.verifyEmail(verificationToken);
122
+
123
+ // Reset password flow
124
+ await authService.initiatePasswordReset('user@example.com');
125
+ await authService.resetPassword(resetToken, 'newPassword');
126
+ ```
127
+
128
+ ### Middleware Usage
129
+
130
+ ```typescript
131
+ import express from 'express';
132
+ import { AuthMiddleware } from '@xcelsior/serverless-auth';
133
+
134
+ const app = express();
135
+ const authMiddleware = new AuthMiddleware(authService);
136
+
137
+ // Protect routes
138
+ app.use(authMiddleware.verifyToken());
139
+
140
+ // Require specific roles
141
+ app.get('/admin',
142
+ authMiddleware.requireRoles(['ADMIN']),
143
+ (req, res) => {
144
+ res.json({ message: 'Admin access granted' });
145
+ }
146
+ );
147
+
148
+ // Require verified email
149
+ app.post('/sensitive-action',
150
+ authMiddleware.requireEmailVerified(),
151
+ (req, res) => {
152
+ res.json({ message: 'Action performed' });
153
+ }
154
+ );
155
+ ```
156
+
157
+ ## Storage Providers
158
+
159
+ ### DynamoDB
160
+
161
+ Create a DynamoDB table with the following structure:
162
+
163
+ - Table Name: (your choice)
164
+ - Partition Key: id (string)
165
+ - GSI (EmailIndex):
166
+ - Partition Key: email (string)
167
+
168
+ ### MongoDB (Coming Soon)
169
+
170
+ The MongoDB provider will support:
171
+ - Custom database and collection names
172
+ - Automatic indexing setup
173
+ - Flexible schema support
174
+
175
+ ### PostgreSQL (Coming Soon)
176
+
177
+ The PostgreSQL provider will support:
178
+ - Custom schema and table names
179
+ - Automatic table creation
180
+ - Migration support
181
+
182
+ ## Email Providers
183
+
184
+ Both email providers come with built-in default templates for:
185
+ - Email verification
186
+ - Password reset
187
+
188
+ The default templates are responsive, mobile-friendly, and follow email best practices. You can override these templates by providing your own in the configuration.
189
+
190
+ ### SMTP
191
+
192
+ The SMTP provider supports any SMTP server, including:
193
+ - Gmail
194
+ - SendGrid
195
+ - Mailgun
196
+ - Custom SMTP servers
197
+
198
+ ### AWS SES
199
+
200
+ The AWS SES provider supports:
201
+ - Direct email sending through AWS SES
202
+ - Region configuration
203
+ - AWS credentials management
204
+ - Production access management
205
+ - Source ARN configuration for verified identities
206
+
207
+ ## Contributing
208
+
209
+ Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
210
+
211
+ ## License
212
+
213
+ MIT
package/biome.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "//"
3
+ }
@@ -0,0 +1,139 @@
1
+ import { z } from 'zod';
2
+
3
+ interface StorageConfig {
4
+ type: 'dynamodb' | 'mongodb' | 'postgres';
5
+ options: DynamoDBConfig | MongoDBConfig | PostgresConfig;
6
+ }
7
+ interface DynamoDBConfig {
8
+ tableName: string;
9
+ region: string;
10
+ }
11
+ interface MongoDBConfig {
12
+ uri: string;
13
+ dbName: string;
14
+ collectionName: string;
15
+ }
16
+ interface PostgresConfig {
17
+ connectionString: string;
18
+ schema?: string;
19
+ tableName: string;
20
+ }
21
+
22
+ interface EmailTemplates {
23
+ verification: {
24
+ subject: string;
25
+ html: (token: string) => string;
26
+ };
27
+ resetPassword: {
28
+ subject: string;
29
+ html: (token: string) => string;
30
+ };
31
+ }
32
+ interface SMTPConfig {
33
+ host: string;
34
+ port: number;
35
+ secure: boolean;
36
+ auth: {
37
+ user: string;
38
+ pass: string;
39
+ };
40
+ }
41
+ interface SESConfig {
42
+ region: string;
43
+ credentials?: {
44
+ accessKeyId: string;
45
+ secretAccessKey: string;
46
+ };
47
+ sourceArn?: string;
48
+ }
49
+ interface EmailConfig {
50
+ type: 'smtp' | 'ses';
51
+ from: string;
52
+ options: SMTPConfig | SESConfig;
53
+ templates?: EmailTemplates;
54
+ }
55
+
56
+ declare const UserRoleSchema: z.ZodEnum<["ADMIN", "USER", "GUEST"]>;
57
+ type UserRole = z.infer<typeof UserRoleSchema>;
58
+ declare const UserSchema: z.ZodObject<{
59
+ id: z.ZodString;
60
+ email: z.ZodString;
61
+ passwordHash: z.ZodString;
62
+ roles: z.ZodArray<z.ZodEnum<["ADMIN", "USER", "GUEST"]>, "many">;
63
+ isEmailVerified: z.ZodBoolean;
64
+ verificationToken: z.ZodOptional<z.ZodString>;
65
+ resetPasswordToken: z.ZodOptional<z.ZodString>;
66
+ resetPasswordExpires: z.ZodOptional<z.ZodNumber>;
67
+ createdAt: z.ZodNumber;
68
+ updatedAt: z.ZodNumber;
69
+ }, "strip", z.ZodTypeAny, {
70
+ id: string;
71
+ email: string;
72
+ passwordHash: string;
73
+ roles: ("ADMIN" | "USER" | "GUEST")[];
74
+ isEmailVerified: boolean;
75
+ createdAt: number;
76
+ updatedAt: number;
77
+ verificationToken?: string | undefined;
78
+ resetPasswordToken?: string | undefined;
79
+ resetPasswordExpires?: number | undefined;
80
+ }, {
81
+ id: string;
82
+ email: string;
83
+ passwordHash: string;
84
+ roles: ("ADMIN" | "USER" | "GUEST")[];
85
+ isEmailVerified: boolean;
86
+ createdAt: number;
87
+ updatedAt: number;
88
+ verificationToken?: string | undefined;
89
+ resetPasswordToken?: string | undefined;
90
+ resetPasswordExpires?: number | undefined;
91
+ }>;
92
+ type User = z.infer<typeof UserSchema>;
93
+ interface AuthConfig {
94
+ jwt: {
95
+ privateKey: string;
96
+ publicKey: string;
97
+ keyId: string;
98
+ expiresIn: string;
99
+ };
100
+ storage: StorageConfig;
101
+ email: EmailConfig;
102
+ }
103
+
104
+ declare class AuthService {
105
+ private storage;
106
+ private email;
107
+ private config;
108
+ constructor(config: AuthConfig);
109
+ private generateToken;
110
+ private hashPassword;
111
+ signup(email: string, password: string, roles?: UserRole[]): Promise<{
112
+ user: User;
113
+ token: string;
114
+ }>;
115
+ signin(email: string, password: string): Promise<{
116
+ user: User;
117
+ token: string;
118
+ }>;
119
+ verifyEmail(token: string): Promise<void>;
120
+ initiatePasswordReset(email: string): Promise<void>;
121
+ resetPassword(token: string, newPassword: string): Promise<void>;
122
+ verifyToken(token: string): Promise<{
123
+ id: string;
124
+ email: string;
125
+ roles: UserRole[];
126
+ isEmailVerified: boolean;
127
+ }>;
128
+ hasRole(userId: string, requiredRoles: UserRole[]): Promise<boolean>;
129
+ }
130
+
131
+ declare class AuthMiddleware {
132
+ private authService;
133
+ constructor(authService: AuthService);
134
+ verifyToken(): (req: any, res: any, next: any) => Promise<void>;
135
+ requireRoles(roles: UserRole[]): (req: any, res: any, next: any) => Promise<void>;
136
+ requireEmailVerified(): (req: any, res: any, next: any) => any;
137
+ }
138
+
139
+ export { type AuthConfig, AuthMiddleware, AuthService, type User, type UserRole, UserRoleSchema, UserSchema };
@@ -0,0 +1,139 @@
1
+ import { z } from 'zod';
2
+
3
+ interface StorageConfig {
4
+ type: 'dynamodb' | 'mongodb' | 'postgres';
5
+ options: DynamoDBConfig | MongoDBConfig | PostgresConfig;
6
+ }
7
+ interface DynamoDBConfig {
8
+ tableName: string;
9
+ region: string;
10
+ }
11
+ interface MongoDBConfig {
12
+ uri: string;
13
+ dbName: string;
14
+ collectionName: string;
15
+ }
16
+ interface PostgresConfig {
17
+ connectionString: string;
18
+ schema?: string;
19
+ tableName: string;
20
+ }
21
+
22
+ interface EmailTemplates {
23
+ verification: {
24
+ subject: string;
25
+ html: (token: string) => string;
26
+ };
27
+ resetPassword: {
28
+ subject: string;
29
+ html: (token: string) => string;
30
+ };
31
+ }
32
+ interface SMTPConfig {
33
+ host: string;
34
+ port: number;
35
+ secure: boolean;
36
+ auth: {
37
+ user: string;
38
+ pass: string;
39
+ };
40
+ }
41
+ interface SESConfig {
42
+ region: string;
43
+ credentials?: {
44
+ accessKeyId: string;
45
+ secretAccessKey: string;
46
+ };
47
+ sourceArn?: string;
48
+ }
49
+ interface EmailConfig {
50
+ type: 'smtp' | 'ses';
51
+ from: string;
52
+ options: SMTPConfig | SESConfig;
53
+ templates?: EmailTemplates;
54
+ }
55
+
56
+ declare const UserRoleSchema: z.ZodEnum<["ADMIN", "USER", "GUEST"]>;
57
+ type UserRole = z.infer<typeof UserRoleSchema>;
58
+ declare const UserSchema: z.ZodObject<{
59
+ id: z.ZodString;
60
+ email: z.ZodString;
61
+ passwordHash: z.ZodString;
62
+ roles: z.ZodArray<z.ZodEnum<["ADMIN", "USER", "GUEST"]>, "many">;
63
+ isEmailVerified: z.ZodBoolean;
64
+ verificationToken: z.ZodOptional<z.ZodString>;
65
+ resetPasswordToken: z.ZodOptional<z.ZodString>;
66
+ resetPasswordExpires: z.ZodOptional<z.ZodNumber>;
67
+ createdAt: z.ZodNumber;
68
+ updatedAt: z.ZodNumber;
69
+ }, "strip", z.ZodTypeAny, {
70
+ id: string;
71
+ email: string;
72
+ passwordHash: string;
73
+ roles: ("ADMIN" | "USER" | "GUEST")[];
74
+ isEmailVerified: boolean;
75
+ createdAt: number;
76
+ updatedAt: number;
77
+ verificationToken?: string | undefined;
78
+ resetPasswordToken?: string | undefined;
79
+ resetPasswordExpires?: number | undefined;
80
+ }, {
81
+ id: string;
82
+ email: string;
83
+ passwordHash: string;
84
+ roles: ("ADMIN" | "USER" | "GUEST")[];
85
+ isEmailVerified: boolean;
86
+ createdAt: number;
87
+ updatedAt: number;
88
+ verificationToken?: string | undefined;
89
+ resetPasswordToken?: string | undefined;
90
+ resetPasswordExpires?: number | undefined;
91
+ }>;
92
+ type User = z.infer<typeof UserSchema>;
93
+ interface AuthConfig {
94
+ jwt: {
95
+ privateKey: string;
96
+ publicKey: string;
97
+ keyId: string;
98
+ expiresIn: string;
99
+ };
100
+ storage: StorageConfig;
101
+ email: EmailConfig;
102
+ }
103
+
104
+ declare class AuthService {
105
+ private storage;
106
+ private email;
107
+ private config;
108
+ constructor(config: AuthConfig);
109
+ private generateToken;
110
+ private hashPassword;
111
+ signup(email: string, password: string, roles?: UserRole[]): Promise<{
112
+ user: User;
113
+ token: string;
114
+ }>;
115
+ signin(email: string, password: string): Promise<{
116
+ user: User;
117
+ token: string;
118
+ }>;
119
+ verifyEmail(token: string): Promise<void>;
120
+ initiatePasswordReset(email: string): Promise<void>;
121
+ resetPassword(token: string, newPassword: string): Promise<void>;
122
+ verifyToken(token: string): Promise<{
123
+ id: string;
124
+ email: string;
125
+ roles: UserRole[];
126
+ isEmailVerified: boolean;
127
+ }>;
128
+ hasRole(userId: string, requiredRoles: UserRole[]): Promise<boolean>;
129
+ }
130
+
131
+ declare class AuthMiddleware {
132
+ private authService;
133
+ constructor(authService: AuthService);
134
+ verifyToken(): (req: any, res: any, next: any) => Promise<void>;
135
+ requireRoles(roles: UserRole[]): (req: any, res: any, next: any) => Promise<void>;
136
+ requireEmailVerified(): (req: any, res: any, next: any) => any;
137
+ }
138
+
139
+ export { type AuthConfig, AuthMiddleware, AuthService, type User, type UserRole, UserRoleSchema, UserSchema };