@ambushsoftworks/nestjs-auth-graphql 0.6.7 → 0.8.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.
Files changed (86) hide show
  1. package/README.md +205 -2
  2. package/dist/auth.module.d.ts +12 -2
  3. package/dist/auth.module.d.ts.map +1 -1
  4. package/dist/auth.module.js +38 -0
  5. package/dist/auth.module.js.map +1 -1
  6. package/dist/constants.d.ts +1 -0
  7. package/dist/constants.d.ts.map +1 -1
  8. package/dist/constants.js +2 -1
  9. package/dist/constants.js.map +1 -1
  10. package/dist/decorators/current-realm.decorator.d.ts +2 -0
  11. package/dist/decorators/current-realm.decorator.d.ts.map +1 -0
  12. package/dist/decorators/current-realm.decorator.js +10 -0
  13. package/dist/decorators/current-realm.decorator.js.map +1 -0
  14. package/dist/dto/jwt-payload.interface.d.ts +1 -0
  15. package/dist/dto/jwt-payload.interface.d.ts.map +1 -1
  16. package/dist/exceptions/invalid-auth-config.exception.d.ts +4 -0
  17. package/dist/exceptions/invalid-auth-config.exception.d.ts.map +1 -0
  18. package/dist/exceptions/invalid-auth-config.exception.js +12 -0
  19. package/dist/exceptions/invalid-auth-config.exception.js.map +1 -0
  20. package/dist/guards/tenant.guard.d.ts.map +1 -1
  21. package/dist/guards/tenant.guard.js +9 -1
  22. package/dist/guards/tenant.guard.js.map +1 -1
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +5 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/interfaces/auth-logger.interface.d.ts +2 -0
  28. package/dist/interfaces/auth-logger.interface.d.ts.map +1 -1
  29. package/dist/interfaces/auth-logger.interface.js +2 -0
  30. package/dist/interfaces/auth-logger.interface.js.map +1 -1
  31. package/dist/interfaces/brute-force-repository.interface.d.ts +1 -0
  32. package/dist/interfaces/brute-force-repository.interface.d.ts.map +1 -1
  33. package/dist/interfaces/jwt-payload-factory.interface.d.ts +1 -0
  34. package/dist/interfaces/jwt-payload-factory.interface.d.ts.map +1 -1
  35. package/dist/interfaces/realm-extractor.interface.d.ts +4 -0
  36. package/dist/interfaces/realm-extractor.interface.d.ts.map +1 -0
  37. package/dist/interfaces/realm-extractor.interface.js +3 -0
  38. package/dist/interfaces/realm-extractor.interface.js.map +1 -0
  39. package/dist/interfaces/tenant-extractor.interface.d.ts +1 -1
  40. package/dist/interfaces/tenant-extractor.interface.d.ts.map +1 -1
  41. package/dist/interfaces/user-repository.interface.d.ts +6 -5
  42. package/dist/interfaces/user-repository.interface.d.ts.map +1 -1
  43. package/dist/middleware/realm.middleware.d.ts +9 -0
  44. package/dist/middleware/realm.middleware.d.ts.map +1 -0
  45. package/dist/middleware/realm.middleware.js +51 -0
  46. package/dist/middleware/realm.middleware.js.map +1 -0
  47. package/dist/repositories/noop-brute-force.repository.d.ts +1 -0
  48. package/dist/repositories/noop-brute-force.repository.d.ts.map +1 -1
  49. package/dist/repositories/noop-brute-force.repository.js +4 -0
  50. package/dist/repositories/noop-brute-force.repository.js.map +1 -1
  51. package/dist/resolvers/base-auth.resolver.d.ts +4 -3
  52. package/dist/resolvers/base-auth.resolver.d.ts.map +1 -1
  53. package/dist/resolvers/base-auth.resolver.js +24 -12
  54. package/dist/resolvers/base-auth.resolver.js.map +1 -1
  55. package/dist/resolvers/oauth.controller.d.ts.map +1 -1
  56. package/dist/resolvers/oauth.controller.js +7 -4
  57. package/dist/resolvers/oauth.controller.js.map +1 -1
  58. package/dist/services/auth.service.d.ts +16 -10
  59. package/dist/services/auth.service.d.ts.map +1 -1
  60. package/dist/services/auth.service.js +67 -48
  61. package/dist/services/auth.service.js.map +1 -1
  62. package/dist/services/brute-force-protection.service.d.ts +14 -7
  63. package/dist/services/brute-force-protection.service.d.ts.map +1 -1
  64. package/dist/services/brute-force-protection.service.js +68 -14
  65. package/dist/services/brute-force-protection.service.js.map +1 -1
  66. package/dist/services/default-jwt-payload-factory.d.ts +1 -0
  67. package/dist/services/default-jwt-payload-factory.d.ts.map +1 -1
  68. package/dist/services/default-jwt-payload-factory.js +5 -1
  69. package/dist/services/default-jwt-payload-factory.js.map +1 -1
  70. package/dist/services/verification.service.d.ts +7 -7
  71. package/dist/services/verification.service.d.ts.map +1 -1
  72. package/dist/services/verification.service.js +17 -17
  73. package/dist/services/verification.service.js.map +1 -1
  74. package/dist/strategies/jwt.strategy.d.ts +3 -1
  75. package/dist/strategies/jwt.strategy.d.ts.map +1 -1
  76. package/dist/strategies/jwt.strategy.js +10 -1
  77. package/dist/strategies/jwt.strategy.js.map +1 -1
  78. package/dist/test-utils/mock-repositories.d.ts.map +1 -1
  79. package/dist/test-utils/mock-repositories.js +1 -0
  80. package/dist/test-utils/mock-repositories.js.map +1 -1
  81. package/dist/utils/ip-hash.d.ts +2 -0
  82. package/dist/utils/ip-hash.d.ts.map +1 -0
  83. package/dist/utils/ip-hash.js +11 -0
  84. package/dist/utils/ip-hash.js.map +1 -0
  85. package/examples/full-resolver-template.ts +305 -0
  86. package/package.json +2 -1
@@ -1,4 +1,5 @@
1
1
  import { Strategy } from 'passport-jwt';
2
+ import type { Request } from 'express';
2
3
  import { AuthService } from '../services/auth.service';
3
4
  import { JwtPayload } from '../dto/jwt-payload.interface';
4
5
  import { IAuthUser } from '../interfaces/auth-user.interface';
@@ -10,8 +11,9 @@ export declare class JwtStrategy extends JwtStrategy_base {
10
11
  private authService;
11
12
  private readonly jwtValidation;
12
13
  private readonly jwtPayloadFactory;
14
+ private readonly realmsEnabled;
13
15
  constructor(options: AuthModuleOptions, authService: AuthService, jwtPayloadFactory?: IJwtPayloadFactory);
14
- validate(payload: JwtPayload): Promise<IAuthUser | JwtPayloadUser>;
16
+ validate(req: Request, payload: JwtPayload): Promise<IAuthUser | JwtPayloadUser>;
15
17
  }
16
18
  export {};
17
19
  //# sourceMappingURL=jwt.strategy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/jwt.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;;AAelE,qBACa,WAAY,SAAQ,gBAA0B;IAMvD,OAAO,CAAC,WAAW;IALrB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;gBAGxB,OAAO,EAAE,iBAAiB,EAC/C,WAAW,EAAE,WAAW,EAGhC,iBAAiB,CAAC,EAAE,kBAAkB;IA4BlC,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,GAAG,cAAc,CAAC;CAwBzE"}
1
+ {"version":3,"file":"jwt.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/jwt.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,QAAQ,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;;AAelE,qBACa,WAAY,SAAQ,gBAA0B;IAOvD,OAAO,CAAC,WAAW;IANrB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAGT,OAAO,EAAE,iBAAiB,EAC/C,WAAW,EAAE,WAAW,EAGhC,iBAAiB,CAAC,EAAE,kBAAkB;IA8BlC,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,GAAG,cAAc,CAAC;CAiCvF"}
@@ -42,12 +42,21 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
42
42
  jwtFromRequest: jwtExtractor,
43
43
  ignoreExpiration: false,
44
44
  secretOrKey: options.jwtSecret,
45
+ passReqToCallback: true,
45
46
  });
46
47
  this.authService = authService;
47
48
  this.jwtValidation = options.jwtValidation || 'full';
48
49
  this.jwtPayloadFactory = jwtPayloadFactory || new default_jwt_payload_factory_1.DefaultJwtPayloadFactory();
50
+ this.realmsEnabled = !!options.realmExtractorInstance;
49
51
  }
50
- async validate(payload) {
52
+ async validate(req, payload) {
53
+ if (this.realmsEnabled) {
54
+ const requestRealm = req._realm;
55
+ const tokenRealm = payload.realm;
56
+ if (!tokenRealm || tokenRealm !== requestRealm) {
57
+ throw new common_1.UnauthorizedException('Invalid token');
58
+ }
59
+ }
51
60
  const userId = this.jwtPayloadFactory.extractUserId(payload);
52
61
  if (this.jwtValidation === 'payload-only') {
53
62
  return { id: userId, email: payload.email };
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../src/strategies/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAqF;AACrF,+CAAoD;AACpD,+CAAoD;AAEpD,2DAAuD;AAIvD,yFAAmF;AACnF,4CAAwE;AAQxE,SAAS,UAAU,CAAC,UAAkB;IACpC,OAAO,CAAC,GAAY,EAAiB,EAAE;QACrC,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,CAAW,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAGM,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,IAAA,2BAAgB,EAAC,uBAAQ,CAAC;IAIzD,YAC+B,OAA0B,EAC/C,WAAwB,EAGhC,iBAAsC;QAEtC,MAAM,eAAe,GAAG,yBAAU,CAAC,2BAA2B,EAAE,CAAC;QAIjE,MAAM,iBAAiB,GAAG,OAAO,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CAAC;QAChE,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,cAAc,CAAC;QAGzE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,aAAa;YAC9C,CAAC,CAAC,UAAU,cAAc,EAAE;YAC5B,CAAC,CAAC,cAAc,CAAC;QAEnB,MAAM,YAAY,GAAG,iBAAiB;YACpC,CAAC,CAAC,yBAAU,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC;YACtE,CAAC,CAAC,eAAe,CAAC;QAEpB,KAAK,CAAC;YACJ,cAAc,EAAE,YAAY;YAC5B,gBAAgB,EAAE,KAAK;YACvB,WAAW,EAAE,OAAO,CAAC,SAAS;SAC/B,CAAC,CAAC;QAzBK,gBAAW,GAAX,WAAW,CAAa;QA2BhC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,MAAM,CAAC;QACrD,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,IAAI,IAAI,sDAAwB,EAAE,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAmB;QAIhC,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE7D,IAAI,IAAI,CAAC,aAAa,KAAK,cAAc,EAAE,CAAC;YAI1C,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9C,CAAC;QAKD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QAE9E,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,8BAAqB,CAAC,eAAe,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA7DY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;IAMR,WAAA,IAAA,eAAM,EAAC,+BAAmB,CAAC,CAAA;IAE3B,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,+BAAmB,CAAC,CAAA;6CAFP,0BAAW;GANvB,WAAW,CA6DvB"}
1
+ {"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../src/strategies/jwt.strategy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mock-repositories.d.ts","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAM/I,wBAAgB,wBAAwB,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAwCvE;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAYvF;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAOvF;AAKD,wBAAgB,8BAA8B,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAQnF;AAKD,wBAAgB,6BAA6B,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAUjF"}
1
+ {"version":3,"file":"mock-repositories.d.ts","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAM/I,wBAAgB,wBAAwB,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAwCvE;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAYvF;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAOvF;AAKD,wBAAgB,8BAA8B,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CASnF;AAKD,wBAAgB,6BAA6B,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAUjF"}
@@ -73,6 +73,7 @@ function createMockBruteForceRepository() {
73
73
  lockAccount: jest.fn(),
74
74
  checkAccountLock: jest.fn(),
75
75
  clearFailedAttempts: jest.fn(),
76
+ deleteOlderThan: jest.fn(),
76
77
  };
77
78
  }
78
79
  function createMockBiometricRepository() {
@@ -1 +1 @@
1
- {"version":3,"file":"mock-repositories.js","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock-repositories.js","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function hashIp(ipAddress: string, salt: string): string;
2
+ //# sourceMappingURL=ip-hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-hash.d.ts","sourceRoot":"","sources":["../../src/utils/ip-hash.ts"],"names":[],"mappings":"AAgCA,wBAAgB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9D"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashIp = hashIp;
4
+ const crypto_1 = require("crypto");
5
+ function hashIp(ipAddress, salt) {
6
+ return (0, crypto_1.createHmac)('sha256', salt)
7
+ .update(ipAddress)
8
+ .digest('hex')
9
+ .slice(0, 16);
10
+ }
11
+ //# sourceMappingURL=ip-hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-hash.js","sourceRoot":"","sources":["../../src/utils/ip-hash.ts"],"names":[],"mappings":";;AAgCA,wBAKC;AArCD,mCAAoC;AAgCpC,SAAgB,MAAM,CAAC,SAAiB,EAAE,IAAY;IACpD,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC;SAC9B,MAAM,CAAC,SAAS,CAAC;SACjB,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,305 @@
1
+ // @ts-nocheck
2
+ //
3
+ // =============================================================================
4
+ // DO NOT IMPORT THIS FILE.
5
+ // =============================================================================
6
+ //
7
+ // This file is a REFERENCE TEMPLATE shipped with @ambushsoftworks/nestjs-auth-graphql.
8
+ // It is intentionally NOT exported from `src/index.ts` and is NOT importable by
9
+ // consumers from the package's barrel.
10
+ //
11
+ // WHY YOU CAN'T JUST IMPORT IT:
12
+ // TypeScript decorator metadata (the type information `@Mutation(() => Foo)`
13
+ // emits via `emitDecoratorMetadata`) is NOT preserved across compiled package
14
+ // boundaries. If this file's `@Mutation`/`@Query` decorators ran inside the
15
+ // package and the consumer imported the result, NestJS's GraphQL schema builder
16
+ // would throw "Cannot determine GraphQL output type" at runtime. The decorators
17
+ // MUST execute inside YOUR project's compilation unit. See the class-level
18
+ // docblock in `BaseAuthResolver` (`src/resolvers/base-auth.resolver.ts`) for
19
+ // the full explanation — this is the same constraint that prevents Item 5 of
20
+ // the Jobsites feature requests from being implementable inside the package.
21
+ //
22
+ // HOW TO USE THIS FILE:
23
+ // 1. Copy it into your own `src/resolvers/` directory and rename it to
24
+ // something like `auth.resolver.ts`.
25
+ // 2. Replace every `MyAuthUser`, `MyAuthResponse`, `MyLoginInput`, etc.
26
+ // placeholder with your project's actual GraphQL types (the placeholders
27
+ // are tagged with `// REPLACE:` comments).
28
+ // 3. Remove the `@ts-nocheck` directive at the top once you've wired in
29
+ // real types — it is only present so the template doesn't fail
30
+ // typechecking when the placeholders are undefined.
31
+ // 4. Register the resolver in your auth module's `providers` array.
32
+ //
33
+ // WHAT THIS TEMPLATE COVERS:
34
+ // Every `perform*` method on `BaseAuthResolver` is wrapped with the
35
+ // appropriate `@Mutation` or `@Query` decorator, plus the recommended
36
+ // `@Throttle` configuration on auth-sensitive endpoints (signup, login,
37
+ // password reset/change). Guards (`@UseGuards(JwtAuthGuard)`) are applied to
38
+ // methods that require an authenticated user.
39
+ //
40
+ // `@ts-nocheck` is used because the placeholder DTO/entity types intentionally
41
+ // don't exist in the package. Copy this file and replace placeholders before
42
+ // use; once your real types are wired in, remove the directive and the file
43
+ // will typecheck normally.
44
+ //
45
+ // =============================================================================
46
+
47
+ import { Resolver, Mutation, Query, Args, Context } from '@nestjs/graphql';
48
+ import { UseGuards } from '@nestjs/common';
49
+ import { Throttle } from '@nestjs/throttler';
50
+ import {
51
+ BaseAuthResolver,
52
+ JwtAuthGuard,
53
+ CurrentUser,
54
+ } from '@ambushsoftworks/nestjs-auth-graphql';
55
+
56
+ // REPLACE: import your project's User entity (must implement IAuthUser).
57
+ import { MyAuthUser } from '../entities/my-auth-user.entity';
58
+
59
+ // REPLACE: import your project's GraphQL ObjectType DTOs.
60
+ import { MyAuthResponse } from '../dto/my-auth-response.dto';
61
+ import { MyLogoutResponse } from '../dto/my-logout-response.dto';
62
+ import { MyLogoutAllResponse } from '../dto/my-logout-all-response.dto';
63
+ import { MyAccountLockStatus } from '../dto/my-account-lock-status.dto';
64
+ import { MyVerifyEmailResponse } from '../dto/my-verify-email-response.dto';
65
+ import { MyPhoneVerificationResponse } from '../dto/my-phone-verification-response.dto';
66
+ import { MyVerifyPhoneResponse } from '../dto/my-verify-phone-response.dto';
67
+ import { MyRemovePhoneResponse } from '../dto/my-remove-phone-response.dto';
68
+ import { MyPhoneVerificationStatus } from '../dto/my-phone-verification-status.dto';
69
+ import { MyPasswordResetResponse } from '../dto/my-password-reset-response.dto';
70
+ import { MyChangePasswordResponse } from '../dto/my-change-password-response.dto';
71
+
72
+ // REPLACE: import your project's GraphQL InputType DTOs.
73
+ import { MySignupInput } from '../dto/my-signup.input';
74
+ import { MyLoginInput } from '../dto/my-login.input';
75
+ import { MyRefreshTokenInput } from '../dto/my-refresh-token.input';
76
+ import { MyLogoutInput } from '../dto/my-logout.input';
77
+ import { MyVerifyEmailInput } from '../dto/my-verify-email.input';
78
+ import { MySendPhoneVerificationInput } from '../dto/my-send-phone-verification.input';
79
+ import { MyVerifyPhoneInput } from '../dto/my-verify-phone.input';
80
+ import { MyRequestPasswordResetInput } from '../dto/my-request-password-reset.input';
81
+ import { MyResetPasswordInput } from '../dto/my-reset-password.input';
82
+ import { MyChangePasswordInput } from '../dto/my-change-password.input';
83
+ import { MyCompleteFacebookSignUpInput } from '../dto/my-complete-facebook-signup.input';
84
+
85
+ /**
86
+ * Full reference auth resolver. Wraps every `perform*` method on
87
+ * `BaseAuthResolver` with the matching GraphQL decorator. Copy and
88
+ * customize — DO NOT import this file from the package.
89
+ */
90
+ @Resolver()
91
+ export class AuthResolver extends BaseAuthResolver<MyAuthUser> {
92
+ // ===========================================================================
93
+ // Core Auth Mutations
94
+ // ===========================================================================
95
+
96
+ @Mutation(() => MyAuthResponse)
97
+ @Throttle({ default: { limit: 5, ttl: 60000 } }) // 5 signups / minute / IP
98
+ async signup(
99
+ @Args('input') input: MySignupInput,
100
+ @Context() ctx: any,
101
+ ): Promise<MyAuthResponse> {
102
+ return this.performSignup(input, ctx) as Promise<MyAuthResponse>;
103
+ }
104
+
105
+ @Mutation(() => MyAuthResponse)
106
+ @Throttle({ default: { limit: 5, ttl: 60000 } }) // 5 logins / minute / IP
107
+ async login(
108
+ @Args('input') input: MyLoginInput,
109
+ @Context() ctx: any,
110
+ ): Promise<MyAuthResponse> {
111
+ return this.performLogin(input, ctx) as Promise<MyAuthResponse>;
112
+ }
113
+
114
+ @Mutation(() => MyAuthResponse)
115
+ async refreshToken(
116
+ @Args('input') input: MyRefreshTokenInput,
117
+ @Context() ctx: any,
118
+ ): Promise<MyAuthResponse> {
119
+ return this.performRefreshToken(input, ctx) as Promise<MyAuthResponse>;
120
+ }
121
+
122
+ @Mutation(() => MyLogoutResponse)
123
+ @UseGuards(JwtAuthGuard)
124
+ async logout(
125
+ @Args('input') input: MyLogoutInput,
126
+ @CurrentUser() user: MyAuthUser,
127
+ @Context() ctx: any,
128
+ ): Promise<MyLogoutResponse> {
129
+ return this.performLogout(input, user, ctx);
130
+ }
131
+
132
+ @Mutation(() => MyLogoutAllResponse)
133
+ @UseGuards(JwtAuthGuard)
134
+ async logoutAll(
135
+ @CurrentUser() user: MyAuthUser,
136
+ @Context() ctx: any,
137
+ ): Promise<MyLogoutAllResponse> {
138
+ return this.performLogoutAll(user, ctx);
139
+ }
140
+
141
+ // ===========================================================================
142
+ // Account Lock Status
143
+ // ===========================================================================
144
+
145
+ @Query(() => MyAccountLockStatus)
146
+ async checkAccountLockStatus(
147
+ @Args('email') email: string,
148
+ ): Promise<MyAccountLockStatus> {
149
+ return this.performCheckAccountLockStatus(email);
150
+ }
151
+
152
+ // ===========================================================================
153
+ // Email Verification
154
+ // ===========================================================================
155
+
156
+ @Mutation(() => MyVerifyEmailResponse)
157
+ async verifyEmail(
158
+ @Args('input') input: MyVerifyEmailInput,
159
+ @Context() ctx: any,
160
+ ): Promise<MyVerifyEmailResponse> {
161
+ return this.performVerifyEmail(input, ctx);
162
+ }
163
+
164
+ @Mutation(() => MyVerifyEmailResponse)
165
+ async resendVerificationEmail(
166
+ @Args('email') email: string,
167
+ @Context() ctx: any,
168
+ ): Promise<MyVerifyEmailResponse> {
169
+ return this.performResendVerificationEmail(email, ctx);
170
+ }
171
+
172
+ // ===========================================================================
173
+ // Phone Verification
174
+ // ===========================================================================
175
+
176
+ @Mutation(() => MyPhoneVerificationResponse)
177
+ @UseGuards(JwtAuthGuard)
178
+ async sendPhoneVerification(
179
+ @Args('input') input: MySendPhoneVerificationInput,
180
+ @CurrentUser() user: MyAuthUser,
181
+ @Context() ctx: any,
182
+ ): Promise<MyPhoneVerificationResponse> {
183
+ return this.performSendPhoneVerification(input, user, ctx);
184
+ }
185
+
186
+ @Mutation(() => MyVerifyPhoneResponse)
187
+ @UseGuards(JwtAuthGuard)
188
+ async verifyPhone(
189
+ @Args('input') input: MyVerifyPhoneInput,
190
+ @CurrentUser() user: MyAuthUser,
191
+ ): Promise<MyVerifyPhoneResponse> {
192
+ return this.performVerifyPhone(input, user);
193
+ }
194
+
195
+ @Mutation(() => MyPhoneVerificationResponse)
196
+ @UseGuards(JwtAuthGuard)
197
+ async resendPhoneVerification(
198
+ @Args('phoneNumber') phoneNumber: string,
199
+ @CurrentUser() user: MyAuthUser,
200
+ ): Promise<MyPhoneVerificationResponse> {
201
+ return this.performResendPhoneVerification(phoneNumber, user);
202
+ }
203
+
204
+ @Mutation(() => MyRemovePhoneResponse)
205
+ @UseGuards(JwtAuthGuard)
206
+ async removePhoneNumber(
207
+ @CurrentUser() user: MyAuthUser,
208
+ ): Promise<MyRemovePhoneResponse> {
209
+ return this.performRemovePhoneNumber(user);
210
+ }
211
+
212
+ @Query(() => MyPhoneVerificationStatus)
213
+ @UseGuards(JwtAuthGuard)
214
+ async phoneVerificationStatus(
215
+ @CurrentUser() user: MyAuthUser,
216
+ ): Promise<MyPhoneVerificationStatus> {
217
+ return this.performPhoneVerificationStatus(user);
218
+ }
219
+
220
+ // ===========================================================================
221
+ // Password Reset
222
+ // ===========================================================================
223
+
224
+ @Mutation(() => MyPasswordResetResponse)
225
+ @Throttle({ default: { limit: 3, ttl: 3600000 } }) // 3 requests / hour / IP
226
+ async requestPasswordReset(
227
+ @Args('input') input: MyRequestPasswordResetInput,
228
+ @Context() ctx: any,
229
+ ): Promise<MyPasswordResetResponse> {
230
+ return this.performRequestPasswordReset(input, ctx);
231
+ }
232
+
233
+ @Mutation(() => MyPasswordResetResponse)
234
+ @Throttle({ default: { limit: 5, ttl: 900000 } }) // 5 attempts / 15 min / IP
235
+ async resetPassword(
236
+ @Args('input') input: MyResetPasswordInput,
237
+ @Context() ctx: any,
238
+ ): Promise<MyPasswordResetResponse> {
239
+ return this.performResetPassword(input, ctx);
240
+ }
241
+
242
+ // ===========================================================================
243
+ // Password Change (authenticated)
244
+ // ===========================================================================
245
+
246
+ /**
247
+ * Change password for the authenticated user.
248
+ *
249
+ * `AuthService.changePassword` revokes ALL refresh tokens for the user
250
+ * (logging them out of every device including the current one). Calling
251
+ * `authService.issueAuthSession(user.id, ctx.res)` after the change keeps
252
+ * the current device logged in by minting a fresh token pair (and writing
253
+ * cookies if cookie auth is enabled).
254
+ */
255
+ @Mutation(() => MyChangePasswordResponse)
256
+ @UseGuards(JwtAuthGuard)
257
+ @Throttle({ default: { limit: 5, ttl: 900000 } }) // 5 attempts / 15 min / IP
258
+ async changePassword(
259
+ @CurrentUser() user: MyAuthUser,
260
+ @Args('input') input: MyChangePasswordInput,
261
+ @Context() ctx: any,
262
+ ): Promise<MyChangePasswordResponse> {
263
+ const result = await this.performChangePassword(
264
+ user.id,
265
+ input.currentPassword,
266
+ input.newPassword,
267
+ );
268
+ // Keep the current device logged in (other devices are revoked above).
269
+ // Use `getResponseFromContext` so cookies work under both Apollo
270
+ // (`ctx.res`) and Express/Fastify (`ctx.req.res`).
271
+ const res = this.getResponseFromContext(ctx);
272
+ const tokens = await this.authService.issueAuthSession(user.id, res);
273
+ return {
274
+ ...result,
275
+ accessToken: tokens.accessToken,
276
+ refreshToken: tokens.refreshToken,
277
+ };
278
+ }
279
+
280
+ // ===========================================================================
281
+ // Current User
282
+ // ===========================================================================
283
+
284
+ @Query(() => MyAuthUser)
285
+ @UseGuards(JwtAuthGuard)
286
+ async me(@CurrentUser() user: MyAuthUser): Promise<MyAuthUser> {
287
+ return this.performGetCurrentUser(user.id);
288
+ }
289
+
290
+ // ===========================================================================
291
+ // Facebook OAuth Email Fallback
292
+ // ===========================================================================
293
+
294
+ @Mutation(() => MyAuthResponse, {
295
+ name: 'completeFacebookSignUp',
296
+ description: 'Complete Facebook sign-up when email not provided by Facebook',
297
+ })
298
+ @Throttle({ default: { limit: 5, ttl: 60000 } })
299
+ async completeFacebookSignUp(
300
+ @Args('input') input: MyCompleteFacebookSignUpInput,
301
+ @Context() ctx: any,
302
+ ): Promise<MyAuthResponse> {
303
+ return this.performCompleteFacebookSignUp(input, ctx) as Promise<MyAuthResponse>;
304
+ }
305
+ }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ambushsoftworks/nestjs-auth-graphql",
3
- "version": "0.6.7",
3
+ "version": "0.8.0",
4
4
  "description": "Production-grade authentication package for NestJS with GraphQL, supporting JWT, OAuth, email/SMS verification, and biometric auth",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
8
  "dist",
9
+ "examples",
9
10
  "README.md",
10
11
  "LICENSE"
11
12
  ],