@tekcify/auth-backend 1.0.0 → 1.0.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.
Files changed (48) hide show
  1. package/README.md +7 -12
  2. package/{src/express/index.ts → dist/express/index.d.ts} +1 -0
  3. package/dist/express/index.d.ts.map +1 -0
  4. package/dist/express/index.js +6 -0
  5. package/dist/express/index.js.map +1 -0
  6. package/dist/express/middleware.d.ts +16 -0
  7. package/dist/express/middleware.d.ts.map +1 -0
  8. package/dist/express/middleware.js +39 -0
  9. package/dist/express/middleware.js.map +1 -0
  10. package/{src/index.ts → dist/index.d.ts} +1 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +22 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/nestjs/decorator.d.ts +2 -0
  15. package/dist/nestjs/decorator.d.ts.map +1 -0
  16. package/dist/nestjs/decorator.js +11 -0
  17. package/dist/nestjs/decorator.js.map +1 -0
  18. package/dist/nestjs/guard.d.ts +13 -0
  19. package/dist/nestjs/guard.d.ts.map +1 -0
  20. package/dist/nestjs/guard.js +56 -0
  21. package/dist/nestjs/guard.js.map +1 -0
  22. package/{src/nestjs/index.ts → dist/nestjs/index.d.ts} +1 -0
  23. package/dist/nestjs/index.d.ts.map +1 -0
  24. package/dist/nestjs/index.js +8 -0
  25. package/dist/nestjs/index.js.map +1 -0
  26. package/dist/types.d.ts +22 -0
  27. package/dist/types.d.ts.map +1 -0
  28. package/dist/types.js +3 -0
  29. package/dist/types.js.map +1 -0
  30. package/dist/userinfo.d.ts +9 -0
  31. package/dist/userinfo.d.ts.map +1 -0
  32. package/dist/userinfo.js +16 -0
  33. package/dist/userinfo.js.map +1 -0
  34. package/dist/verify.d.ts +4 -0
  35. package/dist/verify.d.ts.map +1 -0
  36. package/dist/verify.js +38 -0
  37. package/dist/verify.js.map +1 -0
  38. package/package.json +13 -10
  39. package/src/__tests__/verify.test.ts +0 -80
  40. package/src/express/middleware.ts +0 -61
  41. package/src/nestjs/decorator.ts +0 -12
  42. package/src/nestjs/guard.ts +0 -57
  43. package/src/types.ts +0 -24
  44. package/src/userinfo.ts +0 -26
  45. package/src/verify.ts +0 -36
  46. package/tsconfig.json +0 -11
  47. package/tsconfig.tsbuildinfo +0 -1
  48. package/vitest.config.ts +0 -9
package/README.md CHANGED
@@ -28,9 +28,10 @@ You need the JWT access secret from your Tekcify Auth server. This should match
28
28
 
29
29
  ```env
30
30
  JWT_ACCESS_SECRET=your-jwt-access-secret-here
31
- AUTH_SERVER_URL=http://localhost:7001
32
31
  ```
33
32
 
33
+ **Note:** The auth server URL is centralized in `@tekcify/auth-core-client` package as `AUTH_SERVER_URL` (default: `http://localhost:7002`). Functions that communicate with the auth server use this constant automatically.
34
+
34
35
  ## NestJS Integration
35
36
 
36
37
  ### Step 1: Install Dependencies
@@ -255,7 +256,7 @@ import { introspectToken } from '@tekcify/auth-core-client';
255
256
 
256
257
  const token = req.headers.authorization?.replace('Bearer ', '');
257
258
 
258
- const result = await introspectToken(process.env.AUTH_SERVER_URL!, {
259
+ const result = await introspectToken({
259
260
  token: token!,
260
261
  clientId: process.env.CLIENT_ID,
261
262
  clientSecret: process.env.CLIENT_SECRET,
@@ -277,10 +278,7 @@ Fetch user information from the auth server:
277
278
  ```typescript
278
279
  import { fetchUserInfo } from '@tekcify/auth-backend';
279
280
 
280
- const userInfo = await fetchUserInfo(
281
- process.env.AUTH_SERVER_URL!,
282
- accessToken
283
- );
281
+ const userInfo = await fetchUserInfo(accessToken);
284
282
 
285
283
  console.log('Email:', userInfo.email);
286
284
  console.log('Name:', userInfo.name);
@@ -426,15 +424,12 @@ verifyAccessToken(token: string, {
426
424
  }): VerifiedToken
427
425
  ```
428
426
 
429
- #### `fetchUserInfo(authServerUrl, accessToken)`
427
+ #### `fetchUserInfo(accessToken)`
430
428
 
431
- Fetches user information from the auth server.
429
+ Fetches user information from the Tekcify auth server using the centralized `AUTH_SERVER_URL`.
432
430
 
433
431
  ```typescript
434
- fetchUserInfo(
435
- authServerUrl: string,
436
- accessToken: string
437
- ): Promise<UserInfo>
432
+ fetchUserInfo(accessToken: string): Promise<UserInfo>
438
433
  ```
439
434
 
440
435
  ### Types
@@ -1,2 +1,3 @@
1
1
  export { createAuthMiddleware } from './middleware';
2
2
  export type { ExpressAuthOptions } from './middleware';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuthMiddleware = void 0;
4
+ var middleware_1 = require("./middleware");
5
+ Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return middleware_1.createAuthMiddleware; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":";;;AAAA,2CAAoD;AAA3C,kHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,16 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ import type { VerifyTokenOptions, UserPayload } from '../types';
3
+ export interface ExpressAuthOptions extends VerifyTokenOptions {
4
+ getUserInfo?: (userId: string) => Promise<{
5
+ email: string;
6
+ } | null>;
7
+ }
8
+ declare global {
9
+ namespace Express {
10
+ interface Request {
11
+ user?: UserPayload;
12
+ }
13
+ }
14
+ }
15
+ export declare function createAuthMiddleware(options: ExpressAuthOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
16
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/express/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEhE,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACrE;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE,WAAW,CAAC;SACpB;KACF;CACF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,IAE5D,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,OAAO,CAAC,IAAI,CAAC,CAsCjB"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuthMiddleware = createAuthMiddleware;
4
+ const verify_1 = require("../verify");
5
+ function createAuthMiddleware(options) {
6
+ return async (req, res, next) => {
7
+ const authHeader = req.headers.authorization;
8
+ if (!authHeader?.startsWith('Bearer ')) {
9
+ res
10
+ .status(401)
11
+ .json({ message: 'Missing or invalid authorization header' });
12
+ return;
13
+ }
14
+ const token = authHeader.substring(7);
15
+ const verified = (0, verify_1.verifyAccessToken)(token, options);
16
+ if (!verified.valid) {
17
+ res.status(401).json({ message: 'Invalid or expired token' });
18
+ return;
19
+ }
20
+ let email = '';
21
+ if (options.getUserInfo) {
22
+ const userInfo = await options.getUserInfo(verified.payload.sub);
23
+ if (!userInfo) {
24
+ res.status(401).json({ message: 'User not found' });
25
+ return;
26
+ }
27
+ email = userInfo.email;
28
+ }
29
+ req.user = {
30
+ userId: verified.payload.sub,
31
+ email,
32
+ scopes: Array.isArray(verified.payload.scopes)
33
+ ? verified.payload.scopes
34
+ : [],
35
+ };
36
+ next();
37
+ };
38
+ }
39
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/express/middleware.ts"],"names":[],"mappings":";;AAiBA,oDA2CC;AA3DD,sCAA8C;AAgB9C,SAAgB,oBAAoB,CAAC,OAA2B;IAC9D,OAAO,KAAK,EACV,GAAY,EACZ,GAAa,EACb,IAAkB,EACH,EAAE;QACjB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAmC,CAAC;QAEnE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,GAAG;iBACA,MAAM,CAAC,GAAG,CAAC;iBACX,IAAI,CAAC,EAAE,OAAO,EAAE,yCAAyC,EAAE,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAA,0BAAiB,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YACD,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QACzB,CAAC;QAED,GAAG,CAAC,IAAI,GAAG;YACT,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG;YAC5B,KAAK;YACL,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC5C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM;gBACzB,CAAC,CAAC,EAAE;SACP,CAAC;QAEF,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
@@ -3,3 +3,4 @@ export * from './verify';
3
3
  export * from './userinfo';
4
4
  export * from './nestjs';
5
5
  export * from './express';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./verify"), exports);
19
+ __exportStar(require("./userinfo"), exports);
20
+ __exportStar(require("./nestjs"), exports);
21
+ __exportStar(require("./express"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,2CAAyB;AACzB,6CAA2B;AAC3B,2CAAyB;AACzB,4CAA0B"}
@@ -0,0 +1,2 @@
1
+ export declare const CurrentUser: (...dataOrPipes: unknown[]) => ParameterDecorator;
2
+ //# sourceMappingURL=decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.d.ts","sourceRoot":"","sources":["../../src/nestjs/decorator.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,mDAOvB,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CurrentUser = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.CurrentUser = (0, common_1.createParamDecorator)((data, ctx) => {
6
+ const request = ctx
7
+ .switchToHttp()
8
+ .getRequest();
9
+ return request.user;
10
+ });
11
+ //# sourceMappingURL=decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.js","sourceRoot":"","sources":["../../src/nestjs/decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAI3D,QAAA,WAAW,GAAG,IAAA,6BAAoB,EAC7C,CAAC,IAAa,EAAE,GAAqB,EAA2B,EAAE;IAChE,MAAM,OAAO,GAAG,GAAG;SAChB,YAAY,EAAE;SACd,UAAU,EAAoC,CAAC;IAClD,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC,CACF,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import type { VerifyTokenOptions } from '../types';
3
+ export interface JwtAuthGuardOptions extends VerifyTokenOptions {
4
+ getUserInfo?: (userId: string) => Promise<{
5
+ email: string;
6
+ } | null>;
7
+ }
8
+ export declare class JwtAuthGuard implements CanActivate {
9
+ private readonly options;
10
+ constructor(options: JwtAuthGuardOptions);
11
+ canActivate(context: ExecutionContext): Promise<boolean>;
12
+ }
13
+ //# sourceMappingURL=guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/nestjs/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,UAAU,CAAC;AAEhE,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACrE;AAED,qBACa,YAAa,YAAW,WAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mBAAmB;IAEnD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CAsC/D"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.JwtAuthGuard = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const verify_1 = require("../verify");
15
+ let JwtAuthGuard = class JwtAuthGuard {
16
+ options;
17
+ constructor(options) {
18
+ this.options = options;
19
+ }
20
+ async canActivate(context) {
21
+ const request = context
22
+ .switchToHttp()
23
+ .getRequest();
24
+ const authHeader = request.headers.authorization;
25
+ if (!authHeader?.startsWith('Bearer ')) {
26
+ throw new common_1.UnauthorizedException('Missing or invalid authorization header');
27
+ }
28
+ const token = authHeader.substring(7);
29
+ const verified = (0, verify_1.verifyAccessToken)(token, this.options);
30
+ if (!verified.valid) {
31
+ throw new common_1.UnauthorizedException('Invalid or expired token');
32
+ }
33
+ let email = '';
34
+ if (this.options.getUserInfo) {
35
+ const userInfo = await this.options.getUserInfo(verified.payload.sub);
36
+ if (!userInfo) {
37
+ throw new common_1.UnauthorizedException('User not found');
38
+ }
39
+ email = userInfo.email;
40
+ }
41
+ request.user = {
42
+ userId: verified.payload.sub,
43
+ email,
44
+ scopes: Array.isArray(verified.payload.scopes)
45
+ ? verified.payload.scopes
46
+ : [],
47
+ };
48
+ return true;
49
+ }
50
+ };
51
+ exports.JwtAuthGuard = JwtAuthGuard;
52
+ exports.JwtAuthGuard = JwtAuthGuard = __decorate([
53
+ (0, common_1.Injectable)(),
54
+ __metadata("design:paramtypes", [Object])
55
+ ], JwtAuthGuard);
56
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/nestjs/guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AAExB,sCAA8C;AAQvC,IAAM,YAAY,GAAlB,MAAM,YAAY;IACM;IAA7B,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;IAAG,CAAC;IAE7D,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO;aACpB,YAAY,EAAE;aACd,UAAU,EAAoC,CAAC;QAClD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAmC,CAAC;QAEvE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,8BAAqB,CAC7B,yCAAyC,CAC1C,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAA,0BAAiB,EAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAExD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,8BAAqB,CAAC,0BAA0B,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACtE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,8BAAqB,CAAC,gBAAgB,CAAC,CAAC;YACpD,CAAC;YACD,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QACzB,CAAC;QAED,OAAO,CAAC,IAAI,GAAG;YACb,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG;YAC5B,KAAK;YACL,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC5C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM;gBACzB,CAAC,CAAC,EAAE;SACP,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAzCY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;;GACA,YAAY,CAyCxB"}
@@ -2,3 +2,4 @@ export { JwtAuthGuard } from './guard';
2
2
  export type { JwtAuthGuardOptions } from './guard';
3
3
  export { CurrentUser } from './decorator';
4
4
  export type { UserPayload } from '../types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nestjs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CurrentUser = exports.JwtAuthGuard = void 0;
4
+ var guard_1 = require("./guard");
5
+ Object.defineProperty(exports, "JwtAuthGuard", { enumerable: true, get: function () { return guard_1.JwtAuthGuard; } });
6
+ var decorator_1 = require("./decorator");
7
+ Object.defineProperty(exports, "CurrentUser", { enumerable: true, get: function () { return decorator_1.CurrentUser; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nestjs/index.ts"],"names":[],"mappings":";;;AAAA,iCAAuC;AAA9B,qGAAA,YAAY,OAAA;AAErB,yCAA0C;AAAjC,wGAAA,WAAW,OAAA"}
@@ -0,0 +1,22 @@
1
+ export interface TokenPayload {
2
+ sub: string;
3
+ type: 'access' | 'refresh' | 'temp';
4
+ scopes?: string[];
5
+ clientId?: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface VerifyTokenOptions {
9
+ secret: string;
10
+ issuer?: string;
11
+ audience?: string;
12
+ }
13
+ export interface VerifiedToken {
14
+ payload: TokenPayload;
15
+ valid: boolean;
16
+ }
17
+ export interface UserPayload {
18
+ userId: string;
19
+ email: string;
20
+ scopes?: string[];
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { UserInfo, IntrospectResult } from '@tekcify/auth-core-client';
2
+ export declare function fetchUserInfo(accessToken: string): Promise<UserInfo>;
3
+ export interface IntrospectTokenOptions {
4
+ token: string;
5
+ clientId?: string;
6
+ clientSecret?: string;
7
+ }
8
+ export declare function introspectAccessToken(options: IntrospectTokenOptions): Promise<IntrospectResult>;
9
+ //# sourceMappingURL=userinfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userinfo.d.ts","sourceRoot":"","sources":["../src/userinfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG5E,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE1E;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAM3B"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchUserInfo = fetchUserInfo;
4
+ exports.introspectAccessToken = introspectAccessToken;
5
+ const auth_core_client_1 = require("@tekcify/auth-core-client");
6
+ async function fetchUserInfo(accessToken) {
7
+ return (0, auth_core_client_1.getUserInfo)(accessToken);
8
+ }
9
+ async function introspectAccessToken(options) {
10
+ return (0, auth_core_client_1.introspectToken)({
11
+ token: options.token,
12
+ clientId: options.clientId,
13
+ clientSecret: options.clientSecret,
14
+ });
15
+ }
16
+ //# sourceMappingURL=userinfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userinfo.js","sourceRoot":"","sources":["../src/userinfo.ts"],"names":[],"mappings":";;AAGA,sCAEC;AAQD,sDAQC;AApBD,gEAAyE;AAElE,KAAK,UAAU,aAAa,CAAC,WAAmB;IACrD,OAAO,IAAA,8BAAW,EAAC,WAAW,CAAC,CAAC;AAClC,CAAC;AAQM,KAAK,UAAU,qBAAqB,CACzC,OAA+B;IAE/B,OAAO,IAAA,kCAAe,EAAC;QACrB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { TokenPayload, VerifyTokenOptions, VerifiedToken } from './types';
2
+ export declare function verifyAccessToken(token: string, options: VerifyTokenOptions): VerifiedToken;
3
+ export declare function decodeToken(token: string): TokenPayload | null;
4
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE/E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,kBAAkB,GAC1B,aAAa,CAqBf;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAM9D"}
package/dist/verify.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.verifyAccessToken = verifyAccessToken;
7
+ exports.decodeToken = decodeToken;
8
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
+ function verifyAccessToken(token, options) {
10
+ try {
11
+ const decoded = jsonwebtoken_1.default.verify(token, options.secret, {
12
+ issuer: options.issuer ?? 'tekcify-auth',
13
+ audience: options.audience ?? 'tekcify-api',
14
+ });
15
+ if (decoded.type !== 'access') {
16
+ return { payload: decoded, valid: false };
17
+ }
18
+ return { payload: decoded, valid: true };
19
+ }
20
+ catch (error) {
21
+ if (error instanceof jsonwebtoken_1.default.JsonWebTokenError) {
22
+ return { payload: {}, valid: false };
23
+ }
24
+ if (error instanceof jsonwebtoken_1.default.TokenExpiredError) {
25
+ return { payload: {}, valid: false };
26
+ }
27
+ throw error;
28
+ }
29
+ }
30
+ function decodeToken(token) {
31
+ try {
32
+ return jsonwebtoken_1.default.decode(token);
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":";;;;;AAGA,8CAwBC;AAED,kCAMC;AAnCD,gEAA+B;AAG/B,SAAgB,iBAAiB,CAC/B,KAAa,EACb,OAA2B;IAE3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE;YAChD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc;YACxC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,aAAa;SAC5C,CAAiB,CAAC;QAEnB,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC5C,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,sBAAG,CAAC,iBAAiB,EAAE,CAAC;YAC3C,OAAO,EAAE,OAAO,EAAE,EAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,YAAY,sBAAG,CAAC,iBAAiB,EAAE,CAAC;YAC3C,OAAO,EAAE,OAAO,EAAE,EAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACvD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,IAAI,CAAC;QACH,OAAO,sBAAG,CAAC,MAAM,CAAC,KAAK,CAAwB,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekcify/auth-backend",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Backend authentication helpers for Tekcify Auth. Provides middleware, guards, and utilities for validating JWT tokens and protecting API routes in NestJS and Express applications.",
5
5
  "author": "Tekcify",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,7 @@
31
31
  }
32
32
  },
33
33
  "scripts": {
34
- "build": "tsc",
34
+ "build": "tsc -p tsconfig.build.json",
35
35
  "clean": "rm -rf dist",
36
36
  "lint": "eslint \"src/**/*.ts\" --max-warnings=0",
37
37
  "test": "vitest run",
@@ -44,18 +44,22 @@
44
44
  "jwt",
45
45
  "auth"
46
46
  ],
47
+ "files": [
48
+ "dist",
49
+ "README.md"
50
+ ],
47
51
  "license": "MIT",
48
52
  "dependencies": {
49
- "@tekcify/auth-core-client": "^1.0.0",
50
- "jsonwebtoken": "^9.0.2"
53
+ "@tekcify/auth-core-client": ">=1.0.5",
54
+ "jsonwebtoken": "^9.0.3"
51
55
  },
52
56
  "devDependencies": {
53
- "@nestjs/common": "^11.0.1",
54
- "@nestjs/core": "^11.0.1",
55
- "@types/express": "^5.0.0",
57
+ "@nestjs/common": "^11.1.9",
58
+ "@nestjs/core": "^11.1.9",
59
+ "@types/express": "^5.0.6",
56
60
  "@types/jsonwebtoken": "^9.0.10",
57
- "@types/node": "^22.10.7",
58
- "typescript": "^5.7.3",
61
+ "@types/node": "^24.10.1",
62
+ "typescript": "^5.9.3",
59
63
  "vitest": "^4.0.15"
60
64
  },
61
65
  "peerDependencies": {
@@ -63,4 +67,3 @@
63
67
  "@nestjs/core": "^11.0.0"
64
68
  }
65
69
  }
66
-
@@ -1,80 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import jwt from 'jsonwebtoken';
3
- import { verifyAccessToken } from '../verify';
4
-
5
- describe('verifyAccessToken', () => {
6
- const secret = 'test-secret';
7
- const issuer = 'tekcify-auth';
8
- const audience = 'tekcify-api';
9
-
10
- it('should verify a valid access token', () => {
11
- const payload = {
12
- sub: 'user-123',
13
- type: 'access',
14
- scopes: ['read:profile'],
15
- };
16
-
17
- const token = jwt.sign(payload, secret, {
18
- issuer,
19
- audience,
20
- expiresIn: '1h',
21
- });
22
-
23
- const result = verifyAccessToken(token, { secret, issuer, audience });
24
-
25
- expect(result.valid).toBe(true);
26
- expect(result.payload.sub).toBe('user-123');
27
- expect(result.payload.type).toBe('access');
28
- });
29
-
30
- it('should reject a refresh token', () => {
31
- const payload = {
32
- sub: 'user-123',
33
- type: 'refresh',
34
- };
35
-
36
- const token = jwt.sign(payload, secret, {
37
- issuer,
38
- audience,
39
- expiresIn: '7d',
40
- });
41
-
42
- const result = verifyAccessToken(token, { secret, issuer, audience });
43
-
44
- expect(result.valid).toBe(false);
45
- });
46
-
47
- it('should reject an expired token', () => {
48
- const payload = {
49
- sub: 'user-123',
50
- type: 'access',
51
- };
52
-
53
- const token = jwt.sign(payload, secret, {
54
- issuer,
55
- audience,
56
- expiresIn: '-1h',
57
- });
58
-
59
- const result = verifyAccessToken(token, { secret, issuer, audience });
60
-
61
- expect(result.valid).toBe(false);
62
- });
63
-
64
- it('should reject a token with wrong secret', () => {
65
- const payload = {
66
- sub: 'user-123',
67
- type: 'access',
68
- };
69
-
70
- const token = jwt.sign(payload, 'wrong-secret', {
71
- issuer,
72
- audience,
73
- expiresIn: '1h',
74
- });
75
-
76
- const result = verifyAccessToken(token, { secret, issuer, audience });
77
-
78
- expect(result.valid).toBe(false);
79
- });
80
- });
@@ -1,61 +0,0 @@
1
- import type { Request, Response, NextFunction } from 'express';
2
- import { verifyAccessToken } from '../verify';
3
- import type { VerifyTokenOptions, UserPayload } from '../types';
4
-
5
- export interface ExpressAuthOptions extends VerifyTokenOptions {
6
- getUserInfo?: (userId: string) => Promise<{ email: string } | null>;
7
- }
8
-
9
- declare global {
10
- // eslint-disable-next-line @typescript-eslint/no-namespace
11
- namespace Express {
12
- interface Request {
13
- user?: UserPayload;
14
- }
15
- }
16
- }
17
-
18
- export function createAuthMiddleware(options: ExpressAuthOptions) {
19
- return async (
20
- req: Request,
21
- res: Response,
22
- next: NextFunction,
23
- ): Promise<void> => {
24
- const authHeader = req.headers.authorization as string | undefined;
25
-
26
- if (!authHeader?.startsWith('Bearer ')) {
27
- res
28
- .status(401)
29
- .json({ message: 'Missing or invalid authorization header' });
30
- return;
31
- }
32
-
33
- const token = authHeader.substring(7);
34
- const verified = verifyAccessToken(token, options);
35
-
36
- if (!verified.valid) {
37
- res.status(401).json({ message: 'Invalid or expired token' });
38
- return;
39
- }
40
-
41
- let email = '';
42
- if (options.getUserInfo) {
43
- const userInfo = await options.getUserInfo(verified.payload.sub);
44
- if (!userInfo) {
45
- res.status(401).json({ message: 'User not found' });
46
- return;
47
- }
48
- email = userInfo.email;
49
- }
50
-
51
- req.user = {
52
- userId: verified.payload.sub,
53
- email,
54
- scopes: Array.isArray(verified.payload.scopes)
55
- ? verified.payload.scopes
56
- : [],
57
- };
58
-
59
- next();
60
- };
61
- }
@@ -1,12 +0,0 @@
1
- import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
- import type { Request } from 'express';
3
- import type { UserPayload } from '../types';
4
-
5
- export const CurrentUser = createParamDecorator(
6
- (data: unknown, ctx: ExecutionContext): UserPayload | undefined => {
7
- const request = ctx
8
- .switchToHttp()
9
- .getRequest<Request & { user?: UserPayload }>();
10
- return request.user;
11
- },
12
- );