@ooneex/auth 0.0.20 → 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 +26 -0
- package/dist/index.d.ts +9 -14
- package/dist/index.js +2 -2
- package/dist/index.js.map +4 -4
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -1 +1,27 @@
|
|
|
1
1
|
# @ooneex/auth
|
|
2
|
+
|
|
3
|
+
Authentication framework with pluggable strategies for securing APIs and web applications -- supports token-based and session-based authentication flows.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
✅ **Clerk Integration** - Built-in Clerk authentication client for user and session management
|
|
12
|
+
|
|
13
|
+
✅ **Token Verification** - Bearer token extraction and verification via Clerk backend
|
|
14
|
+
|
|
15
|
+
✅ **Auth Middleware** - Ready-to-use ClerkAuthMiddleware for protecting routes
|
|
16
|
+
|
|
17
|
+
✅ **User Management** - Get, update, ban, lock, unlock, and delete users through the Clerk API
|
|
18
|
+
|
|
19
|
+
✅ **Session Management** - Retrieve sessions and sign out users programmatically
|
|
20
|
+
|
|
21
|
+
✅ **User Metadata** - Read and update public, private, and unsafe metadata on user profiles
|
|
22
|
+
|
|
23
|
+
✅ **Profile Images** - Update and delete user profile images
|
|
24
|
+
|
|
25
|
+
✅ **Dependency Injection** - Injectable classes that integrate with the Ooneex DI container
|
|
26
|
+
|
|
27
|
+
✅ **Custom Exceptions** - AuthException with HTTP status codes for structured error handling
|
package/dist/index.d.ts
CHANGED
|
@@ -3,10 +3,13 @@ declare class AuthException extends Exception {
|
|
|
3
3
|
constructor(message: string, data?: Record<string, unknown>);
|
|
4
4
|
}
|
|
5
5
|
import { Session, User } from "@clerk/backend";
|
|
6
|
+
type ClerkAuthConfigType = {
|
|
7
|
+
secretKey?: string;
|
|
8
|
+
};
|
|
6
9
|
declare class ClerkAuth {
|
|
7
10
|
private readonly client;
|
|
8
11
|
private readonly secretKey;
|
|
9
|
-
constructor();
|
|
12
|
+
constructor(config?: ClerkAuthConfigType);
|
|
10
13
|
getCurrentUser(token: string): Promise<User | null>;
|
|
11
14
|
banUser(userId: string): Promise<User>;
|
|
12
15
|
unbanUser(userId: string): Promise<User>;
|
|
@@ -29,19 +32,11 @@ declare class ClerkAuth {
|
|
|
29
32
|
getCurrentUserSession(token: string): Promise<Session | null>;
|
|
30
33
|
signOut(sessionId: string): Promise<Session>;
|
|
31
34
|
}
|
|
32
|
-
import { ContextConfigType as ContextConfigType2, ContextType as ContextType2 } from "@ooneex/controller";
|
|
33
|
-
import { UserRepository } from "@ooneex/typeorm/repositories/user";
|
|
34
|
-
import { IUser as IUser2 } from "@ooneex/user";
|
|
35
35
|
import { ContextConfigType, ContextType } from "@ooneex/controller";
|
|
36
|
-
import {
|
|
37
|
-
|
|
38
|
-
interface IAuthMiddleware<T extends ContextConfigType = ContextConfigType> {
|
|
39
|
-
handler: (context: ContextType<T>) => Promise<IUser> | IUser;
|
|
40
|
-
}
|
|
41
|
-
declare class ClerkAuthMiddleware implements IAuthMiddleware {
|
|
36
|
+
import { IMiddleware } from "@ooneex/middleware";
|
|
37
|
+
declare class ClerkAuthMiddleware implements IMiddleware {
|
|
42
38
|
private readonly clerkAuth;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
handler<T extends ContextConfigType2>(context: ContextType2<T>): Promise<IUser2>;
|
|
39
|
+
constructor(clerkAuth: ClerkAuth);
|
|
40
|
+
handler<T extends ContextConfigType>(context: ContextType<T>): Promise<ContextType<T>>;
|
|
46
41
|
}
|
|
47
|
-
export {
|
|
42
|
+
export { ClerkAuthMiddleware, ClerkAuthConfigType, ClerkAuth, AuthException };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
2
|
+
var c=function(e,t,r,a){var s=arguments.length,i=s<3?t:a===null?a=Object.getOwnPropertyDescriptor(t,r):a,u;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")i=Reflect.decorate(e,t,r,a);else for(var m=e.length-1;m>=0;m--)if(u=e[m])i=(s<3?u(i):s>3?u(t,r,i):u(t,r))||i;return s>3&&i&&Object.defineProperty(t,r,i),i},f=(e,t)=>(r,a)=>t(r,a,e),l=(e,t)=>{if(typeof Reflect==="object"&&typeof Reflect.metadata==="function")return Reflect.metadata(e,t)};import{Exception as U}from"@ooneex/exception";import{HttpStatus as g}from"@ooneex/http-status";class n extends U{constructor(e,t={}){super(e,{status:g.Code.InternalServerError,data:t});this.name="AuthException"}}import{createClerkClient as h,verifyToken as y}from"@clerk/backend";import{injectable as b}from"@ooneex/container";class o{client;secretKey;constructor(e){let t=e?.secretKey||Bun.env.CLERK_SECRET_KEY;if(!t)throw new n("Clerk secret key is required. Provide a secret key through config options or set the CLERK_SECRET_KEY environment variable.");this.secretKey=t,this.client=h({secretKey:t})}async getCurrentUser(e){let{sub:t}=await y(e,{secretKey:this.secretKey});if(!t)return null;return await this.getUser(t)}async banUser(e){return await this.client.users.banUser(e)}async unbanUser(e){return await this.client.users.unbanUser(e)}async getUser(e){return await this.client.users.getUser(e)}async lockUser(e){return await this.client.users.lockUser(e)}async unlockUser(e){return await this.client.users.unlockUser(e)}async updateUser(e,t){return await this.client.users.updateUser(e,t)}async updateUserProfileImage(e,t){return await this.client.users.updateUserProfileImage(e,t)}async updateUserMetadata(e,t){return await this.client.users.updateUserMetadata(e,t)}async getUserMetadata(e){let t=await this.getUser(e);return{publicMetadata:t.publicMetadata,privateMetadata:t.privateMetadata,unsafeMetadata:t.unsafeMetadata}}async deleteUser(e){return await this.client.users.deleteUser(e)}async deleteUserProfileImage(e){return await this.client.users.deleteUserProfileImage(e)}async getSession(e){return await this.client.sessions.getSession(e)}async getCurrentUserSession(e){let{sid:t}=await y(e,{secretKey:this.secretKey});if(!t)return null;return await this.getSession(t)}async signOut(e){return await this.client.sessions.revokeSession(e)}}o=c([b(),l("design:paramtypes",[typeof ClerkAuthConfigType==="undefined"?Object:ClerkAuthConfigType])],o);import{inject as w,injectable as A}from"@ooneex/container";import{HttpStatus as d}from"@ooneex/http-status";import{ERole as x}from"@ooneex/role";class p{clerkAuth;constructor(e){this.clerkAuth=e}async handler(e){let t=e.header.getBearerToken();if(!t)throw new n("Authentication required: Missing bearer token",{status:d.Code.Unauthorized});let r=await this.clerkAuth.getCurrentUser(t);if(!r)throw new n("Authentication failed: Invalid or expired token",{status:d.Code.Unauthorized});let a=r.emailAddresses.find((i)=>i.id===r.primaryEmailAddressId);if(!a)throw new n("User has no primary email",{status:d.Code.Unauthorized});let s={id:r.privateMetadata?.externalId,externalId:r.id,email:a.emailAddress,roles:r.privateMetadata?.roles??[x.USER]};if(r.firstName)s.firstName=r.firstName;if(r.lastName)s.lastName=r.lastName;if(r.username)s.username=r.username;if(r.phoneNumbers[0]?.phoneNumber)s.phone=r.phoneNumbers[0].phoneNumber;if(r.lastActiveAt)s.lastActiveAt=new Date(r.lastActiveAt);if(r.lastSignInAt)s.lastLoginAt=new Date(r.lastSignInAt);if(r.imageUrl)s.avatar=r.imageUrl;if(r.createdAt)s.createdAt=new Date(r.createdAt);if(r.updatedAt)s.updatedAt=new Date(r.updatedAt);return e.user=s,e}}p=c([A(),f(0,w(o)),l("design:paramtypes",[typeof o==="undefined"?Object:o])],p);export{p as ClerkAuthMiddleware,o as ClerkAuth,n as AuthException};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=4AAA1A1EEBE4A80C64756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"sources": ["src/AuthException.ts", "src/ClerkAuth.ts", "src/ClerkAuthMiddleware.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class AuthException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"AuthException\";\n }\n}\n",
|
|
6
|
-
"import { createClerkClient, type Session, type User, verifyToken } from \"@clerk/backend\";\nimport { injectable } from \"@ooneex/container\";\nimport { AuthException } from \"./AuthException\";\n\n@injectable()\nexport class ClerkAuth {\n private readonly client: ReturnType<typeof createClerkClient>;\n private readonly secretKey: string;\n\n constructor() {\n const secretKey =
|
|
7
|
-
"import { inject } from \"@ooneex/container\";\nimport type { ContextConfigType, ContextType } from \"@ooneex/controller\";\nimport { HttpStatus } from \"@ooneex/http-status\";\nimport {
|
|
6
|
+
"import { createClerkClient, type Session, type User, verifyToken } from \"@clerk/backend\";\nimport { injectable } from \"@ooneex/container\";\nimport { AuthException } from \"./AuthException\";\nimport type { ClerkAuthConfigType } from \"./types\";\n\n@injectable()\nexport class ClerkAuth {\n private readonly client: ReturnType<typeof createClerkClient>;\n private readonly secretKey: string;\n\n constructor(config?: ClerkAuthConfigType) {\n const secretKey = config?.secretKey || Bun.env.CLERK_SECRET_KEY;\n\n if (!secretKey) {\n throw new AuthException(\n \"Clerk secret key is required. Provide a secret key through config options or set the CLERK_SECRET_KEY environment variable.\",\n );\n }\n\n this.secretKey = secretKey;\n this.client = createClerkClient({\n secretKey,\n });\n }\n\n public async getCurrentUser(token: string): Promise<User | null> {\n const { sub: userId } = await verifyToken(token, {\n secretKey: this.secretKey,\n });\n\n if (!userId) {\n return null;\n }\n\n return await this.getUser(userId);\n }\n\n public async banUser(userId: string): Promise<User> {\n return await this.client.users.banUser(userId);\n }\n\n public async unbanUser(userId: string): Promise<User> {\n return await this.client.users.unbanUser(userId);\n }\n\n public async getUser(userId: string): Promise<User> {\n return await this.client.users.getUser(userId);\n }\n\n public async lockUser(userId: string): Promise<User> {\n return await this.client.users.lockUser(userId);\n }\n\n public async unlockUser(userId: string): Promise<User> {\n return await this.client.users.unlockUser(userId);\n }\n\n public async updateUser(userId: string, params: Parameters<typeof this.client.users.updateUser>[1]): Promise<User> {\n return await this.client.users.updateUser(userId, params);\n }\n\n public async updateUserProfileImage(userId: string, params: { file: Blob | File }): Promise<User> {\n return await this.client.users.updateUserProfileImage(userId, params);\n }\n\n public async updateUserMetadata(\n userId: string,\n params: Parameters<typeof this.client.users.updateUserMetadata>[1],\n ): Promise<User> {\n return await this.client.users.updateUserMetadata(userId, params);\n }\n\n public async getUserMetadata(userId: string): Promise<{\n publicMetadata: User[\"publicMetadata\"];\n privateMetadata: User[\"privateMetadata\"];\n unsafeMetadata: User[\"unsafeMetadata\"];\n }> {\n const user = await this.getUser(userId);\n return {\n publicMetadata: user.publicMetadata,\n privateMetadata: user.privateMetadata,\n unsafeMetadata: user.unsafeMetadata,\n };\n }\n\n public async deleteUser(userId: string): Promise<User> {\n return await this.client.users.deleteUser(userId);\n }\n\n public async deleteUserProfileImage(userId: string): Promise<User> {\n return await this.client.users.deleteUserProfileImage(userId);\n }\n\n public async getSession(sessionId: string): Promise<Session> {\n return await this.client.sessions.getSession(sessionId);\n }\n\n public async getCurrentUserSession(token: string): Promise<Session | null> {\n const { sid: sessionId } = await verifyToken(token, {\n secretKey: this.secretKey,\n });\n\n if (!sessionId) {\n return null;\n }\n\n return await this.getSession(sessionId);\n }\n\n public async signOut(sessionId: string): Promise<Session> {\n return await this.client.sessions.revokeSession(sessionId);\n }\n}\n",
|
|
7
|
+
"import { inject, injectable } from \"@ooneex/container\";\nimport type { ContextConfigType, ContextType } from \"@ooneex/controller\";\nimport { HttpStatus } from \"@ooneex/http-status\";\nimport type { IMiddleware } from \"@ooneex/middleware\";\nimport { ERole } from \"@ooneex/role\";\nimport type { IUser } from \"@ooneex/user\";\nimport { AuthException } from \"./AuthException\";\nimport { ClerkAuth } from \"./ClerkAuth\";\n\n@injectable()\nexport class ClerkAuthMiddleware implements IMiddleware {\n constructor(@inject(ClerkAuth) private readonly clerkAuth: ClerkAuth) {}\n\n public async handler<T extends ContextConfigType>(context: ContextType<T>): Promise<ContextType<T>> {\n const token = context.header.getBearerToken();\n\n if (!token) {\n throw new AuthException(\"Authentication required: Missing bearer token\", {\n status: HttpStatus.Code.Unauthorized,\n });\n }\n\n const clerkUser = await this.clerkAuth.getCurrentUser(token);\n\n if (!clerkUser) {\n throw new AuthException(\"Authentication failed: Invalid or expired token\", {\n status: HttpStatus.Code.Unauthorized,\n });\n }\n\n const primaryEmail = clerkUser.emailAddresses.find((e) => e.id === clerkUser.primaryEmailAddressId);\n\n if (!primaryEmail) {\n throw new AuthException(\"User has no primary email\", {\n status: HttpStatus.Code.Unauthorized,\n });\n }\n\n const user: IUser = {\n id: clerkUser.privateMetadata?.externalId as string,\n externalId: clerkUser.id,\n email: primaryEmail.emailAddress,\n roles: (clerkUser.privateMetadata?.roles as ERole[]) ?? [ERole.USER],\n };\n\n if (clerkUser.firstName) user.firstName = clerkUser.firstName;\n if (clerkUser.lastName) user.lastName = clerkUser.lastName;\n if (clerkUser.username) user.username = clerkUser.username;\n if (clerkUser.phoneNumbers[0]?.phoneNumber) user.phone = clerkUser.phoneNumbers[0].phoneNumber;\n if (clerkUser.lastActiveAt) user.lastActiveAt = new Date(clerkUser.lastActiveAt);\n if (clerkUser.lastSignInAt) user.lastLoginAt = new Date(clerkUser.lastSignInAt);\n if (clerkUser.imageUrl) user.avatar = clerkUser.imageUrl;\n if (clerkUser.createdAt) user.createdAt = new Date(clerkUser.createdAt);\n if (clerkUser.updatedAt) user.updatedAt = new Date(clerkUser.updatedAt);\n\n context.user = user;\n\n return context;\n }\n}\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": ";8cAAA,oBAAS,0BACT,qBAAS,4BAEF,MAAM,UAAsB,CAAU,CAC3C,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,oBACxB,MACF,CAAC,EACD,KAAK,KAAO,gBAEhB,CCXA,4BAAS,iBAA4C,uBACrD,qBAAS,
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "4AAA1A1EEBE4A80C64756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/auth",
|
|
3
|
-
"description": "Authentication
|
|
4
|
-
"version": "0.0
|
|
3
|
+
"description": "Authentication framework with pluggable strategies for securing APIs and web applications — supports token-based and session-based authentication flows",
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@clerk/backend": "^1.24.1",
|
|
31
|
-
"@ooneex/container": "0.0.
|
|
32
|
-
"@ooneex/controller": "0.
|
|
33
|
-
"@ooneex/exception": "0.0.
|
|
34
|
-
"@ooneex/http-status": "0.0.
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
"@ooneex/container": "0.0.19",
|
|
32
|
+
"@ooneex/controller": "0.17.1",
|
|
33
|
+
"@ooneex/exception": "0.0.18",
|
|
34
|
+
"@ooneex/http-status": "0.0.18"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@ooneex/middleware": "0.17.1",
|
|
38
|
+
"@ooneex/user": "0.0.19"
|
|
37
39
|
},
|
|
38
|
-
"devDependencies": {},
|
|
39
40
|
"keywords": [
|
|
40
41
|
"auth",
|
|
41
42
|
"authentication",
|