rez_core 2.2.169 → 2.2.171

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 (35) hide show
  1. package/dist/module/notification/controller/notification.controller.d.ts +2 -1
  2. package/dist/module/notification/controller/notification.controller.js +15 -2
  3. package/dist/module/notification/controller/notification.controller.js.map +1 -1
  4. package/dist/module/notification/entity/notification.entity.d.ts +1 -0
  5. package/dist/module/notification/entity/notification.entity.js +4 -0
  6. package/dist/module/notification/entity/notification.entity.js.map +1 -1
  7. package/dist/module/notification/firebase-admin.config.d.ts +6 -1
  8. package/dist/module/notification/firebase-admin.config.js +20 -6
  9. package/dist/module/notification/firebase-admin.config.js.map +1 -1
  10. package/dist/module/notification/notification.module.js +17 -3
  11. package/dist/module/notification/notification.module.js.map +1 -1
  12. package/dist/module/notification/service/notification.service.d.ts +19 -0
  13. package/dist/module/notification/service/notification.service.js +88 -0
  14. package/dist/module/notification/service/notification.service.js.map +1 -0
  15. package/dist/module/user/service/user.service.js +2 -0
  16. package/dist/module/user/service/user.service.js.map +1 -1
  17. package/dist/module/workflow/service/task.service.d.ts +1 -1
  18. package/dist/module/workflow/service/task.service.js +2 -2
  19. package/dist/module/workflow/service/task.service.js.map +1 -1
  20. package/dist/tsconfig.build.tsbuildinfo +1 -1
  21. package/package.json +1 -1
  22. package/src/module/notification/controller/notification.controller.ts +10 -2
  23. package/src/module/notification/entity/notification.entity.ts +3 -0
  24. package/src/module/notification/firebase-admin.config.ts +20 -6
  25. package/src/module/notification/notification.module.ts +18 -4
  26. package/src/module/notification/service/notification.service.ts +90 -0
  27. package/src/module/user/service/user.service.ts +4 -0
  28. package/src/module/workflow/service/task.service.ts +1 -1
  29. package/src/resources/dev.properties.yaml +11 -7
  30. package/dist/module/notification/firebase-admin.json +0 -13
  31. package/dist/module/notification/service/firebase.service.d.ts +0 -11
  32. package/dist/module/notification/service/firebase.service.js +0 -40
  33. package/dist/module/notification/service/firebase.service.js.map +0 -1
  34. package/src/module/notification/firebase-admin.json +0 -13
  35. package/src/module/notification/service/firebase.service.ts +0 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.2.169",
3
+ "version": "2.2.171",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -1,5 +1,6 @@
1
- import { Body, Controller, Post } from '@nestjs/common';
2
- import { NotificationsService } from '../service/firebase.service';
1
+ import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common';
2
+ import { JwtAuthGuard } from 'src/module/auth/guards/jwt.guard';
3
+ import { NotificationsService } from '../service/notification.service';
3
4
 
4
5
  @Controller('notifications')
5
6
  export class NotificationsController {
@@ -22,4 +23,11 @@ export class NotificationsController {
22
23
  body.message,
23
24
  );
24
25
  }
26
+
27
+ @Get('all')
28
+ @UseGuards(JwtAuthGuard)
29
+ async getNotifications(@Req() req: any) {
30
+ const loggedInUser = req.user.userData;
31
+ return this.notificationsService.getAllNotifications(loggedInUser);
32
+ }
25
33
  }
@@ -17,4 +17,7 @@ export class NotificationData extends BaseEntity {
17
17
 
18
18
  @Column({ nullable: true })
19
19
  mapped_entity_type: string;
20
+
21
+ @Column({ name: 'is_read', type: 'boolean', default: false })
22
+ is_read: boolean;
20
23
  }
@@ -1,8 +1,22 @@
1
+ // firebase-admin.provider.ts
2
+ import { ConfigService } from '@nestjs/config';
1
3
  import * as admin from 'firebase-admin';
2
- import * as serviceAccount from './firebase-admin.json';
3
4
 
4
- admin.initializeApp({
5
- credential: admin.credential.cert(serviceAccount as admin.ServiceAccount),
6
- });
7
-
8
- export const firebaseAdmin = admin;
5
+ export const FirebaseAdminProvider = {
6
+ provide: 'FIREBASE_ADMIN',
7
+ inject: [ConfigService],
8
+ useFactory: async (configService: ConfigService) => {
9
+ if (!admin.apps.length) {
10
+ admin.initializeApp({
11
+ credential: admin.credential.cert({
12
+ projectId: configService.get<string>('FIREBASE_PROJECT_ID'),
13
+ clientEmail: configService.get<string>('FIREBASE_CLIENT_EMAIL'),
14
+ privateKey: configService
15
+ .get<string>('FIREBASE_PRIVATE_KEY')
16
+ ?.replace(/\\n/g, '\n'),
17
+ }),
18
+ });
19
+ }
20
+ return admin;
21
+ },
22
+ };
@@ -1,4 +1,4 @@
1
- import { forwardRef, Module } from '@nestjs/common';
1
+ import { Module } from '@nestjs/common';
2
2
  import { OtpService } from './service/otp.service';
3
3
  import { OtpRepository } from './repository/otp.repository';
4
4
  import { TypeOrmModule } from '@nestjs/typeorm';
@@ -14,7 +14,9 @@ import { UserModule } from '../user/user.module';
14
14
  import { IcsMeetingModule } from '../ics/ics.module';
15
15
  import { NotificationData } from './entity/notification.entity';
16
16
  import { NotificationsController } from './controller/notification.controller';
17
- import { NotificationsService } from './service/firebase.service';
17
+ import { NotificationsService } from './service/notification.service';
18
+ import { EntityModule } from '../meta/entity.module';
19
+ import { FirebaseAdminProvider } from './firebase-admin.config';
18
20
 
19
21
  @Module({
20
22
  imports: [
@@ -47,9 +49,21 @@ import { NotificationsService } from './service/firebase.service';
47
49
  AuthModule,
48
50
  UserModule,
49
51
  IcsMeetingModule,
52
+ EntityModule,
53
+ ],
54
+ providers: [
55
+ OtpService,
56
+ OtpRepository,
57
+ EmailService,
58
+ NotificationsService,
59
+ FirebaseAdminProvider,
60
+ ],
61
+ exports: [
62
+ OtpService,
63
+ EmailService,
64
+ FirebaseAdminProvider,
65
+ NotificationsService,
50
66
  ],
51
- providers: [OtpService, OtpRepository, EmailService, NotificationsService],
52
- exports: [OtpService, EmailService, NotificationsService],
53
67
  controllers: [OtpController, NotificationsController],
54
68
  })
55
69
  export class NotificationModule {}
@@ -0,0 +1,90 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { DataSource } from 'typeorm';
3
+ import { MediaDataService } from 'src/module/meta/service/media-data.service';
4
+ import * as admin from 'firebase-admin';
5
+
6
+ @Injectable()
7
+ export class NotificationsService {
8
+ constructor(
9
+ private readonly dataSource: DataSource,
10
+ private readonly mediaDataService: MediaDataService,
11
+ @Inject('FIREBASE_ADMIN') private readonly firebaseAdmin: typeof admin,
12
+ ) {}
13
+
14
+ private tokens: Map<string, string> = new Map(); // store in memory for now
15
+
16
+ async saveToken(userId: string | undefined, token: string) {
17
+ if (userId) {
18
+ this.tokens.set(userId, token);
19
+ }
20
+ return { success: true, token };
21
+ }
22
+
23
+ async sendToDevice(token: string, title: string, body: string) {
24
+ const message = {
25
+ token,
26
+ notification: { title, body },
27
+ };
28
+
29
+ return this.firebaseAdmin.messaging().send(message);
30
+ }
31
+
32
+ // Helper: send to a registered user by userId
33
+ async sendToUser(userId: string, title: string, body: string) {
34
+ const token = this.tokens.get(userId);
35
+ if (!token) return { error: 'No token found for user' };
36
+
37
+ return this.sendToDevice(token, title, body);
38
+ }
39
+
40
+ async getAllNotifications(loggedInUser: any) {
41
+ const { id, level_id, level_type } = loggedInUser;
42
+
43
+ const notifications = await this.dataSource.query(
44
+ `
45
+ SELECT
46
+ n.*,
47
+ u.name AS user_name,
48
+ u.profile_image AS user_profile
49
+ FROM cr_notification n
50
+ LEFT JOIN eth_user_profile u ON n.user_id = u.parent_id
51
+ WHERE n.user_id = ? AND n.level_id = ? AND n.level_type = ?
52
+ ORDER BY n.created_date DESC
53
+ `,
54
+ [id, level_id, 'SCH'],
55
+ );
56
+
57
+ // Profile media enrichment
58
+ const mediaCache = new Map();
59
+ for (const notification of notifications) {
60
+ notification.is_read = true;
61
+
62
+ if (notification.user_profile) {
63
+ if (!mediaCache.has(notification.user_profile)) {
64
+ const url = await this.mediaDataService.getMediaDownloadUrl(
65
+ notification.user_profile,
66
+ loggedInUser,
67
+ );
68
+ mediaCache.set(notification.user_profile, url);
69
+ }
70
+ notification.user_profile = mediaCache.get(notification.user_profile);
71
+ } else {
72
+ notification.user_profile = null;
73
+ }
74
+ }
75
+
76
+ // Batch update all fetched notifications
77
+ if (notifications.length > 0) {
78
+ await this.dataSource.query(
79
+ `
80
+ UPDATE cr_notification
81
+ SET is_read = 1
82
+ WHERE user_id = ? AND level_id = ? AND level_type = ?
83
+ `,
84
+ [id, level_id, level_type],
85
+ );
86
+ }
87
+
88
+ return notifications;
89
+ }
90
+ }
@@ -307,6 +307,8 @@ export class UserService extends EntityServiceImpl {
307
307
  }): Promise<any> {
308
308
  const { email, subdomain } = data;
309
309
 
310
+ console.log('Email and Subdomain', email, subdomain);
311
+
310
312
  if (!email || !subdomain) {
311
313
  return { success: false, message: 'Email and Subdomain is required' };
312
314
  }
@@ -324,6 +326,8 @@ export class UserService extends EntityServiceImpl {
324
326
  }
325
327
  }
326
328
 
329
+ console.log('Email and Subdomain 2nd', email, subdomain);
330
+
327
331
  // 🔹 Step 2: Find the user by email + organization check
328
332
  const user = await this.userRepository.findByEmailId(email);
329
333
 
@@ -9,7 +9,7 @@ import { ActivityLogService } from './activity-log.service';
9
9
  import { ACTIVITY_CATEGORIES } from '../repository/activity-log.repository';
10
10
  import { MediaDataService } from 'src/module/meta/service/media-data.service';
11
11
  import { Cron, CronExpression } from '@nestjs/schedule';
12
- import { NotificationsService } from 'src/module/notification/service/firebase.service';
12
+ import { NotificationsService } from 'src/module/notification/service/notification.service';
13
13
 
14
14
  @Injectable()
15
15
  export class TaskService extends EntityServiceImpl {
@@ -1,4 +1,4 @@
1
- DB_HOST: "13.234.25.234"
1
+ DB_HOST: '13.234.25.234'
2
2
  # DB_HOST: 'localhost'
3
3
  DB_PORT: '3306'
4
4
  DB_USER: 'root'
@@ -16,9 +16,13 @@ OTP_LENGTH: '6'
16
16
  VERIFY_OTP: 'false'
17
17
  DEFAULT_OTP: '123456'
18
18
  TOKEN_EXPIRY: 1
19
- # AWS:
20
- # S3:
21
- # AWS_ACCESS_KEY_ID: "AKIAYYKIBDDSQF3KILGE"
22
- # AWS_SECRET_KEY: "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"
23
- # AWS_REGION: "ap-south-1"
24
- # BUCKET_NAME: "testether"
19
+ AWS:
20
+ S3:
21
+ AWS_ACCESS_KEY_ID: 'AKIAYYKIBDDSQF3KILGE'
22
+ AWS_SECRET_KEY: 'PPDMAeO2mVUY1w2f46n/dlt5l9+7NY7E9twJb9LU'
23
+ AWS_REGION: 'ap-south-1'
24
+ BUCKET_NAME: 'testether'
25
+
26
+ FIREBASE_PROJECT_ID: 'sample-d7855'
27
+ FIREBASE_CLIENT_EMAIL: 'firebase-adminsdk-fbsvc@sample-d7855.iam.gserviceaccount.com'
28
+ FIREBASE_PRIVATE_KEY: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwGkpDLqFYgDEW\nnrraMja7ICmd05rJlsTachdcbB25Jm2cWMv1ROfNqWEZE3b14pUJOQgCAPI79Lgj\n+nQ0ATsUWK8Th2esKT9kaHg54UZg/qKNcnM5njVn+xIXc+i/AP/eSGBLich+uljU\nRMFuKrpcN1yNa3t0ib+kZxLHE43aFM9aJYOhET6/37DUdFMZ7GyzSLH3tuy1gB2G\negFyC7ulLnyMBFtL37XOtnP3BPwbjVWdP0qv9I6c0aacS5dQ4PNjCBklnkr6tPsc\n0MYr3VUrqNd/xNNOgk26TwoOaePjjjeaSeOGO2FcBG6WsYSLoZ3zmrlCT4vBlXL7\nPaZGQGfjAgMBAAECggEAHtsMZgcWmCYl87uuK6sesdzpzdCUz3uOVGQnObdr4dQc\n4ocgfYIsR3nFHJqvflfMG0iV4Zv+1YiEdzFcCPyqOF9tlbNk8+JqTBKN9j5FkZss\nKjKCg/b3jpeMTPWvM0BelLkDvliO+7108QR3C/GKo7vDiLfrcrjsDkdNH/qKIUq3\nkHeQE0QDLaoe3sLL4mjPp5A4SnnNBInk1gQZS2iVhTgDAAlSOz7JocyVZr3QhxmF\nUlKYzzJVx8zxIJm3ymH6z6NQNbWnBGWF1eeSZgYRkJG1q+Aqm3kRU/uT3V0HPsvZ\nrg4JGkzM/qFA2mpKuj4ysWGfvERKaEe4Ua84SvbcYQKBgQDjjvgBpQL2V71Ssr2E\nWJO/8Bv3TutWODWEvTRv3woQmuZwT81yIR3R8Ir59xLK0oBQCAONvKnrB5RM5yXQ\nmR6hvyKHFUKWTRqwGCFiD4fh0joO4zQTaFDdbqMYyeTJ4r2W66wXbRXtUvuwhDlg\nmDKamZ1E+EAoYkog6/iNYIcwswKBgQDGHO0n2r8yXYm7dM+EYONGLh76IvxVXJDn\nN8igi1zI2fV3cfUuwXaVlMYUa//aRkNXrBvPdXZEvfRRRLkm6dYLbFZ4Sq6T+NUT\noYNan13R59E6UcA/Oi5jitq9l4Wwn8pDaCbmmR1xdj7+r+H9A5N3BXHeuPLy0f48\nyEY8GF8kEQKBgQDCzhmyDrlCekoxCaMEMXAK2FqYlI8S+HuYbwD85EuRe4nai/as\nxXzpxKq04rbLuvjtim7AX8p20b47N4Y/1VVL0nyUd7bRRKCcL4wkjncc8wOQyyBB\nnQPdDGHDTtL1oY38LTTduR0UVf3xVsBn2OM5RlhEOuFxsPMUy+2z2fbh0QKBgBz3\nMb14AChvAKpFw+mI+PHT4HeWEeqxJAaKY20Fs0UyiO8z3DM/2gS4wdVOjRPu3f29\njjtg4y/dzhDryV5lJgR5jJL96FR+NzktjjT7xA3ipPav6TnVWd73+E9sDgHq+vms\nCrQAgwuJzGAUeygxE6h9RU7ZH7xc850TcyFqNs7hAoGBAMviFpBfpZz/amStyan+\nIPBGpDNV8dUrRE1POIdi6M44mlrI5hkD1ldVl3wjDJtg4VGkMosltLtvC0dDcIou\nuWZT8ENKM2G400PvQ9JJYah9dTkYQL1qMxvpX+biMoRSiAswPwRQjmBQUaz1aN1g\nmXv1VJBLLZVg8x1ckLDjeD20\n-----END PRIVATE KEY-----\n'
@@ -1,13 +0,0 @@
1
- {
2
- "type": "service_account",
3
- "project_id": "sample-d7855",
4
- "private_key_id": "753237e3e7d64a87155b916deda9f3d1cb9cdd52",
5
- "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQChrgvD+0M3u8EU\ntm3xV27RGuYRSjIpZIRi6I3tH0BTwpOde4DnwZWUQnTEbg/wgBGvFtGS7T4UXaef\ngkhTSRqPhIqEaIVRXf34NOhYTAOxBcvDaG9skQbOzhH9gz8cEG1HyDRCWqmxgpCy\nt0jUig5Ta72t0zSaQKc/H6AhwWF8Yiz+KnwGR837FvKDM+ZN28B21sRNcOciDXHf\nEeh4H4GjBQguM+5aMGFRACclIFztwxwTBXCJ2r/AMxSjCntzOCHimgG6dOtlW/KS\neZqunZjxvbmHZpj3N1sGRJQFHFjRLQSgCdMzwOclJ82AImcOYLJ3w1kKTmts6JlW\nVYvj6jzpAgMBAAECggEAA9xhIYv1ffY41SLKG1JILiwjRFRuQDjLRIVjJj9xzM4/\nsioJ2P7xcHnpyesK7GZShcjYtlZ9/gSChTeaPIrpXHYAzMqmLFw/PVceGUWvbOHD\njOYIiyIndHbNTS1+K1BlG6q3PMJnfPquM+ZWkeS+FNXk0KrTfb9/fu1laIjyqAKy\na8w7IwNkk4iBkKxRc74204TxQsgUpooROuoP9JfoVVL90R1EDFJWnrciTcqB77SS\nAFsPbOY9kZ5WOmUp6ZzkQD434fRRCUis7WdicV4OU0VEQmLX57UxzxNTOZzw8Adn\nnn7nmFXfcF5+ODX1htkTSn84p+qP4CR+a99/4rLqgQKBgQDbbsySP4I0KBhXT+xQ\n8iHpTo8lV71R1t4gboBIQXIHkmlrI9Qy/oOe3yViATp54oH727W/vWm4OEomzpl4\nNrs27HrI65XZcYyRCU6mLEaDx2ZjYYKHLMwx0DdQ9MPn+n1JusadiRN671ZZ3smb\nbtMLqeslmoN43SPDiG2CSNOycQKBgQC8n3RViNpHZJDUQoLxHZ7rpfIa/0v3qpjd\nI3nDxDH8udu2ipsVjqXmGJTBY+NQcWhuvuhYTzH5plnSuD3tBrPnA3VoN7FFDd29\nx+5K60acjgbu0sa9yO4aSAYD7sjkfkxVAKhzIgNWlAzl2zluakq5r3+uGQ+FVvJh\nmo5FxSj9+QKBgBkaBqrgOvvObmJmkSj9WeW/h96Et/KJuuVI3sHlQq8dD5QjCB5B\nQTtGWZdpfo/82lO+YX8qotJhFhJ0Zdf7otT4nl8nm//A3oyk3OtjezmN8OeDexQN\nitpT8FABf/ukivqJNDlHOgRBJsanFrcCKYBXEsA9eba0zWeLzsMto5HxAoGBAIaH\nW5udzcDZkwownd+GdtAvPSvQJchwnjIqmS/tAJH1pSTeWpnXca9YnNAJhBjdqdRC\nyMgjQ8uAv9OwoEorW6hKKTS5c++CYkJ3FBfPEj+adItlPWYipt+Luu6XIiUFhz+h\nBoOHIMZhNYnC/4UmvkENUI1FRnKdfqXqa8qLQh9RAoGBAMxOm2fMUKzLPY8xqp0j\nWmo3ZYMkRRi/BFqVn1F+aFGx0ahW8GVT70qy30rhiNJAkl2QnPnllQ6rD/CBc3UT\n3kJLwTc5BWXP1nKxEOuu33xB5wk4mIzyItFf/eYhYFzsWMpJo2gaKE3iNNUKUP0W\nG2coAWXT2iRSS6OHh9B1bRnQ\n-----END PRIVATE KEY-----\n",
6
- "client_email": "firebase-adminsdk-fbsvc@sample-d7855.iam.gserviceaccount.com",
7
- "client_id": "115995668082397151669",
8
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9
- "token_uri": "https://oauth2.googleapis.com/token",
10
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
11
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40sample-d7855.iam.gserviceaccount.com",
12
- "universe_domain": "googleapis.com"
13
- }
@@ -1,11 +0,0 @@
1
- export declare class NotificationsService {
2
- private tokens;
3
- saveToken(userId: string | undefined, token: string): Promise<{
4
- success: boolean;
5
- token: string;
6
- }>;
7
- sendToDevice(token: string, title: string, body: string): Promise<string>;
8
- sendToUser(userId: string, title: string, body: string): Promise<string | {
9
- error: string;
10
- }>;
11
- }
@@ -1,40 +0,0 @@
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
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.NotificationsService = void 0;
10
- const common_1 = require("@nestjs/common");
11
- const firebase_admin_config_1 = require("../firebase-admin.config");
12
- let NotificationsService = class NotificationsService {
13
- constructor() {
14
- this.tokens = new Map();
15
- }
16
- async saveToken(userId, token) {
17
- if (userId) {
18
- this.tokens.set(userId, token);
19
- }
20
- return { success: true, token };
21
- }
22
- async sendToDevice(token, title, body) {
23
- const message = {
24
- token,
25
- notification: { title, body },
26
- };
27
- return firebase_admin_config_1.firebaseAdmin.messaging().send(message);
28
- }
29
- async sendToUser(userId, title, body) {
30
- const token = this.tokens.get(userId);
31
- if (!token)
32
- return { error: 'No token found for user' };
33
- return this.sendToDevice(token, title, body);
34
- }
35
- };
36
- exports.NotificationsService = NotificationsService;
37
- exports.NotificationsService = NotificationsService = __decorate([
38
- (0, common_1.Injectable)()
39
- ], NotificationsService);
40
- //# sourceMappingURL=firebase.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firebase.service.js","sourceRoot":"","sources":["../../../../src/module/notification/service/firebase.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAC5C,oEAAyD;AAGlD,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAA1B;QACG,WAAM,GAAwB,IAAI,GAAG,EAAE,CAAC;IAyBlD,CAAC;IAvBC,KAAK,CAAC,SAAS,CAAC,MAA0B,EAAE,KAAa;QACvD,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,KAAa,EAAE,IAAY;QAC3D,MAAM,OAAO,GAAG;YACd,KAAK;YACL,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;SAC9B,CAAC;QAEF,OAAO,qCAAa,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAGD,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,KAAa,EAAE,IAAY;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;QAExD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;CACF,CAAA;AA1BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;GACA,oBAAoB,CA0BhC"}
@@ -1,13 +0,0 @@
1
- {
2
- "type": "service_account",
3
- "project_id": "sample-d7855",
4
- "private_key_id": "753237e3e7d64a87155b916deda9f3d1cb9cdd52",
5
- "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQChrgvD+0M3u8EU\ntm3xV27RGuYRSjIpZIRi6I3tH0BTwpOde4DnwZWUQnTEbg/wgBGvFtGS7T4UXaef\ngkhTSRqPhIqEaIVRXf34NOhYTAOxBcvDaG9skQbOzhH9gz8cEG1HyDRCWqmxgpCy\nt0jUig5Ta72t0zSaQKc/H6AhwWF8Yiz+KnwGR837FvKDM+ZN28B21sRNcOciDXHf\nEeh4H4GjBQguM+5aMGFRACclIFztwxwTBXCJ2r/AMxSjCntzOCHimgG6dOtlW/KS\neZqunZjxvbmHZpj3N1sGRJQFHFjRLQSgCdMzwOclJ82AImcOYLJ3w1kKTmts6JlW\nVYvj6jzpAgMBAAECggEAA9xhIYv1ffY41SLKG1JILiwjRFRuQDjLRIVjJj9xzM4/\nsioJ2P7xcHnpyesK7GZShcjYtlZ9/gSChTeaPIrpXHYAzMqmLFw/PVceGUWvbOHD\njOYIiyIndHbNTS1+K1BlG6q3PMJnfPquM+ZWkeS+FNXk0KrTfb9/fu1laIjyqAKy\na8w7IwNkk4iBkKxRc74204TxQsgUpooROuoP9JfoVVL90R1EDFJWnrciTcqB77SS\nAFsPbOY9kZ5WOmUp6ZzkQD434fRRCUis7WdicV4OU0VEQmLX57UxzxNTOZzw8Adn\nnn7nmFXfcF5+ODX1htkTSn84p+qP4CR+a99/4rLqgQKBgQDbbsySP4I0KBhXT+xQ\n8iHpTo8lV71R1t4gboBIQXIHkmlrI9Qy/oOe3yViATp54oH727W/vWm4OEomzpl4\nNrs27HrI65XZcYyRCU6mLEaDx2ZjYYKHLMwx0DdQ9MPn+n1JusadiRN671ZZ3smb\nbtMLqeslmoN43SPDiG2CSNOycQKBgQC8n3RViNpHZJDUQoLxHZ7rpfIa/0v3qpjd\nI3nDxDH8udu2ipsVjqXmGJTBY+NQcWhuvuhYTzH5plnSuD3tBrPnA3VoN7FFDd29\nx+5K60acjgbu0sa9yO4aSAYD7sjkfkxVAKhzIgNWlAzl2zluakq5r3+uGQ+FVvJh\nmo5FxSj9+QKBgBkaBqrgOvvObmJmkSj9WeW/h96Et/KJuuVI3sHlQq8dD5QjCB5B\nQTtGWZdpfo/82lO+YX8qotJhFhJ0Zdf7otT4nl8nm//A3oyk3OtjezmN8OeDexQN\nitpT8FABf/ukivqJNDlHOgRBJsanFrcCKYBXEsA9eba0zWeLzsMto5HxAoGBAIaH\nW5udzcDZkwownd+GdtAvPSvQJchwnjIqmS/tAJH1pSTeWpnXca9YnNAJhBjdqdRC\nyMgjQ8uAv9OwoEorW6hKKTS5c++CYkJ3FBfPEj+adItlPWYipt+Luu6XIiUFhz+h\nBoOHIMZhNYnC/4UmvkENUI1FRnKdfqXqa8qLQh9RAoGBAMxOm2fMUKzLPY8xqp0j\nWmo3ZYMkRRi/BFqVn1F+aFGx0ahW8GVT70qy30rhiNJAkl2QnPnllQ6rD/CBc3UT\n3kJLwTc5BWXP1nKxEOuu33xB5wk4mIzyItFf/eYhYFzsWMpJo2gaKE3iNNUKUP0W\nG2coAWXT2iRSS6OHh9B1bRnQ\n-----END PRIVATE KEY-----\n",
6
- "client_email": "firebase-adminsdk-fbsvc@sample-d7855.iam.gserviceaccount.com",
7
- "client_id": "115995668082397151669",
8
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9
- "token_uri": "https://oauth2.googleapis.com/token",
10
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
11
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40sample-d7855.iam.gserviceaccount.com",
12
- "universe_domain": "googleapis.com"
13
- }
@@ -1,31 +0,0 @@
1
- import { Injectable } from '@nestjs/common';
2
- import { firebaseAdmin } from '../firebase-admin.config';
3
-
4
- @Injectable()
5
- export class NotificationsService {
6
- private tokens: Map<string, string> = new Map(); // store in memory for now
7
-
8
- async saveToken(userId: string | undefined, token: string) {
9
- if (userId) {
10
- this.tokens.set(userId, token);
11
- }
12
- return { success: true, token };
13
- }
14
-
15
- async sendToDevice(token: string, title: string, body: string) {
16
- const message = {
17
- token,
18
- notification: { title, body },
19
- };
20
-
21
- return firebaseAdmin.messaging().send(message);
22
- }
23
-
24
- // Helper: send to a registered user by userId
25
- async sendToUser(userId: string, title: string, body: string) {
26
- const token = this.tokens.get(userId);
27
- if (!token) return { error: 'No token found for user' };
28
-
29
- return this.sendToDevice(token, title, body);
30
- }
31
- }