nestjs-mailbridge 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/dist/calendar/calendar-feature.module.d.ts +4 -0
- package/dist/calendar/calendar-feature.module.js +33 -0
- package/dist/calendar/calendar.repository.d.ts +15 -0
- package/dist/calendar/calendar.repository.js +77 -0
- package/dist/calendar/calendar.service.d.ts +34 -0
- package/dist/calendar/calendar.service.js +213 -0
- package/dist/calendar/dto/create-calendar.dto.d.ts +8 -0
- package/dist/calendar/dto/create-calendar.dto.js +51 -0
- package/dist/calendar/dto/update-calendar.dto.d.ts +5 -0
- package/dist/calendar/dto/update-calendar.dto.js +8 -0
- package/dist/calendar/oauth/google-oauth.service.d.ts +13 -0
- package/dist/calendar/oauth/google-oauth.service.js +63 -0
- package/dist/calendar/oauth/outlook-calendar.service.d.ts +13 -0
- package/dist/calendar/oauth/outlook-calendar.service.js +63 -0
- package/dist/dto/send-email.dto.d.ts +6 -0
- package/dist/dto/send-email.dto.js +33 -0
- package/dist/email-feature.module.d.ts +8 -0
- package/dist/email-feature.module.js +37 -0
- package/dist/email.repository.d.ts +11 -0
- package/dist/email.repository.js +72 -0
- package/dist/email.service.d.ts +12 -0
- package/dist/email.service.js +51 -0
- package/dist/email.types.d.ts +54 -0
- package/dist/email.types.js +6 -0
- package/dist/google/gmail-parser.d.ts +3 -0
- package/dist/google/gmail-parser.js +18 -0
- package/dist/google/google-auth.service.d.ts +10 -0
- package/dist/google/google-auth.service.js +53 -0
- package/dist/google/google-gmail.service.d.ts +31 -0
- package/dist/google/google-gmail.service.js +157 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +25 -0
- package/package.json +26 -0
|
@@ -0,0 +1,33 @@
|
|
|
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 CalendarFeatureModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CalendarFeatureModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const calendar_service_1 = require("./calendar.service");
|
|
13
|
+
const calendar_repository_1 = require("./calendar.repository");
|
|
14
|
+
const google_oauth_service_1 = require("./oauth/google-oauth.service");
|
|
15
|
+
const email_feature_module_1 = require("../email-feature.module");
|
|
16
|
+
let CalendarFeatureModule = CalendarFeatureModule_1 = class CalendarFeatureModule {
|
|
17
|
+
static forRoot() {
|
|
18
|
+
return {
|
|
19
|
+
module: CalendarFeatureModule_1,
|
|
20
|
+
imports: [email_feature_module_1.EmailFeatureModule],
|
|
21
|
+
providers: [
|
|
22
|
+
calendar_service_1.CalendarService,
|
|
23
|
+
calendar_repository_1.CalendarRepository,
|
|
24
|
+
google_oauth_service_1.GoogleOAuthService,
|
|
25
|
+
],
|
|
26
|
+
exports: [calendar_service_1.CalendarService],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.CalendarFeatureModule = CalendarFeatureModule;
|
|
31
|
+
exports.CalendarFeatureModule = CalendarFeatureModule = CalendarFeatureModule_1 = __decorate([
|
|
32
|
+
(0, common_1.Module)({})
|
|
33
|
+
], CalendarFeatureModule);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PrismaLike } from "../email.types";
|
|
2
|
+
export declare class CalendarRepository {
|
|
3
|
+
private prisma;
|
|
4
|
+
constructor(prisma: PrismaLike);
|
|
5
|
+
findUserById(id: string): any;
|
|
6
|
+
findUserByEmail(email: string): any;
|
|
7
|
+
updateUser(id: string, data: any): any;
|
|
8
|
+
createEvent(data: any): any;
|
|
9
|
+
findUserEvents(userId: string): any;
|
|
10
|
+
findEvent(id: string, userId: string): any;
|
|
11
|
+
updateEvent(id: string, data: any): any;
|
|
12
|
+
deleteEvent(id: string): any;
|
|
13
|
+
findUnsyncedEvents(userId: string): any;
|
|
14
|
+
findConflict(userId: string, start: Date, end: Date): any;
|
|
15
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CalendarRepository = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const email_types_1 = require("../email.types");
|
|
18
|
+
let CalendarRepository = class CalendarRepository {
|
|
19
|
+
constructor(prisma) {
|
|
20
|
+
this.prisma = prisma;
|
|
21
|
+
}
|
|
22
|
+
findUserById(id) {
|
|
23
|
+
return this.prisma.user.findUnique({ where: { id } });
|
|
24
|
+
}
|
|
25
|
+
findUserByEmail(email) {
|
|
26
|
+
return this.prisma.user.findUnique({ where: { email } });
|
|
27
|
+
}
|
|
28
|
+
updateUser(id, data) {
|
|
29
|
+
return this.prisma.user.update({
|
|
30
|
+
where: { id },
|
|
31
|
+
data,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
createEvent(data) {
|
|
35
|
+
return this.prisma.calendarEvent.create({ data });
|
|
36
|
+
}
|
|
37
|
+
findUserEvents(userId) {
|
|
38
|
+
return this.prisma.calendarEvent.findMany({
|
|
39
|
+
where: { userId },
|
|
40
|
+
orderBy: { startTime: "asc" },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
findEvent(id, userId) {
|
|
44
|
+
return this.prisma.calendarEvent.findFirst({
|
|
45
|
+
where: { id, userId },
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
updateEvent(id, data) {
|
|
49
|
+
return this.prisma.calendarEvent.update({
|
|
50
|
+
where: { id },
|
|
51
|
+
data,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
deleteEvent(id) {
|
|
55
|
+
return this.prisma.calendarEvent.delete({ where: { id } });
|
|
56
|
+
}
|
|
57
|
+
findUnsyncedEvents(userId) {
|
|
58
|
+
return this.prisma.calendarEvent.findMany({
|
|
59
|
+
where: { userId, googleEventId: null },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
findConflict(userId, start, end) {
|
|
63
|
+
return this.prisma.calendarEvent.findFirst({
|
|
64
|
+
where: {
|
|
65
|
+
userId,
|
|
66
|
+
startTime: { lt: end },
|
|
67
|
+
endTime: { gt: start },
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.CalendarRepository = CalendarRepository;
|
|
73
|
+
exports.CalendarRepository = CalendarRepository = __decorate([
|
|
74
|
+
(0, common_1.Injectable)(),
|
|
75
|
+
__param(0, (0, common_1.Inject)(email_types_1.EMAIL_PRISMA)),
|
|
76
|
+
__metadata("design:paramtypes", [Object])
|
|
77
|
+
], CalendarRepository);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CalendarRepository } from "./calendar.repository";
|
|
2
|
+
import { GoogleOAuthService } from "./oauth/google-oauth.service";
|
|
3
|
+
import { CreateCalendarDto } from "./dto/create-calendar.dto";
|
|
4
|
+
import { UpdateCalendarDto } from "./dto/update-calendar.dto";
|
|
5
|
+
export declare class CalendarService {
|
|
6
|
+
private readonly repo;
|
|
7
|
+
private readonly googleOAuth;
|
|
8
|
+
constructor(repo: CalendarRepository, googleOAuth: GoogleOAuthService);
|
|
9
|
+
getGoogleConnectionStatus(userId: string): Promise<{
|
|
10
|
+
connected: boolean;
|
|
11
|
+
email: any;
|
|
12
|
+
userId: any;
|
|
13
|
+
}>;
|
|
14
|
+
getGoogleAuthUrl(userId: string): Promise<{
|
|
15
|
+
url: string;
|
|
16
|
+
}>;
|
|
17
|
+
handleGoogleCallback(code: string, email: string): Promise<{
|
|
18
|
+
connected: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
private getGoogleClient;
|
|
21
|
+
create(dto: CreateCalendarDto, userId: string): Promise<any>;
|
|
22
|
+
createByUserIdNoAuth(userId: string, dto: CreateCalendarDto): Promise<any>;
|
|
23
|
+
findAll(userId: string): any;
|
|
24
|
+
findByUserId(userId: string): any;
|
|
25
|
+
findOne(id: string, userId: string): Promise<any>;
|
|
26
|
+
update(id: string, dto: UpdateCalendarDto, userId: string): Promise<any>;
|
|
27
|
+
remove(id: string, userId: string): Promise<any>;
|
|
28
|
+
private defaultEndTime;
|
|
29
|
+
syncToGoogle(eventId: string, userId: string): Promise<{
|
|
30
|
+
googleEventId: string | null | undefined;
|
|
31
|
+
htmlLink: string | null | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
syncAllToGoogle(userId: string): Promise<any[]>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
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.CalendarService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const googleapis_1 = require("googleapis");
|
|
15
|
+
const calendar_repository_1 = require("./calendar.repository");
|
|
16
|
+
const google_oauth_service_1 = require("./oauth/google-oauth.service");
|
|
17
|
+
let CalendarService = class CalendarService {
|
|
18
|
+
constructor(repo, googleOAuth) {
|
|
19
|
+
this.repo = repo;
|
|
20
|
+
this.googleOAuth = googleOAuth;
|
|
21
|
+
}
|
|
22
|
+
// ---- Google OAuth ----
|
|
23
|
+
async getGoogleConnectionStatus(userId) {
|
|
24
|
+
const user = await this.repo.findUserById(userId);
|
|
25
|
+
if (!user)
|
|
26
|
+
throw new common_1.NotFoundException("User not found");
|
|
27
|
+
return {
|
|
28
|
+
connected: !!user.googleAccessToken,
|
|
29
|
+
email: user.email,
|
|
30
|
+
userId: user.id,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async getGoogleAuthUrl(userId) {
|
|
34
|
+
const user = await this.repo.findUserById(userId);
|
|
35
|
+
if (!user)
|
|
36
|
+
throw new common_1.NotFoundException("User not found");
|
|
37
|
+
if (!user.email)
|
|
38
|
+
throw new common_1.BadRequestException("User email missing");
|
|
39
|
+
return { url: this.googleOAuth.getAuthUrl(user.email) };
|
|
40
|
+
}
|
|
41
|
+
async handleGoogleCallback(code, email) {
|
|
42
|
+
const tokens = await this.googleOAuth.exchangeCode(code);
|
|
43
|
+
const user = await this.repo.findUserByEmail(email);
|
|
44
|
+
if (!user)
|
|
45
|
+
throw new common_1.NotFoundException("User not found");
|
|
46
|
+
// IMPORTANT: refresh_token may be missing if user already authorized before.
|
|
47
|
+
// Your controller already uses prompt=consent, so most cases will be ok.
|
|
48
|
+
await this.repo.updateUser(user.id, {
|
|
49
|
+
googleAccessToken: tokens.access_token ?? null,
|
|
50
|
+
googleRefreshToken: tokens.refresh_token ?? user.googleRefreshToken ?? null,
|
|
51
|
+
googleCalendarConnected: true,
|
|
52
|
+
});
|
|
53
|
+
return { connected: true };
|
|
54
|
+
}
|
|
55
|
+
async getGoogleClient(userId) {
|
|
56
|
+
const user = await this.repo.findUserById(userId);
|
|
57
|
+
if (!user)
|
|
58
|
+
throw new common_1.NotFoundException("User not found");
|
|
59
|
+
if (!user.googleAccessToken)
|
|
60
|
+
throw new common_1.UnauthorizedException("Google not connected");
|
|
61
|
+
const auth = await this.googleOAuth.createClient(user.googleAccessToken, user.googleRefreshToken);
|
|
62
|
+
return googleapis_1.google.calendar({ version: "v3", auth });
|
|
63
|
+
}
|
|
64
|
+
// ---- CRUD ----
|
|
65
|
+
async create(dto, userId) {
|
|
66
|
+
const user = await this.repo.findUserById(userId);
|
|
67
|
+
if (!user)
|
|
68
|
+
throw new common_1.NotFoundException("User not found");
|
|
69
|
+
const start = new Date(dto.startTime);
|
|
70
|
+
const end = dto.endTime ? new Date(dto.endTime) : null;
|
|
71
|
+
return this.repo.createEvent({
|
|
72
|
+
title: dto.title,
|
|
73
|
+
description: dto.description ?? null,
|
|
74
|
+
startTime: start,
|
|
75
|
+
endTime: end,
|
|
76
|
+
userId,
|
|
77
|
+
property: dto.property ?? null,
|
|
78
|
+
tags: dto.tags ?? null,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async createByUserIdNoAuth(userId, dto) {
|
|
82
|
+
const user = await this.repo.findUserById(userId);
|
|
83
|
+
if (!user)
|
|
84
|
+
throw new common_1.BadRequestException("User does not exist");
|
|
85
|
+
const start = new Date(dto.startTime);
|
|
86
|
+
const end = dto.endTime
|
|
87
|
+
? new Date(dto.endTime)
|
|
88
|
+
: new Date(start.getTime() + 60 * 60 * 1000);
|
|
89
|
+
const conflict = await this.repo.findConflict(userId, start, end);
|
|
90
|
+
if (conflict)
|
|
91
|
+
throw new common_1.BadRequestException("Time conflict");
|
|
92
|
+
return this.repo.createEvent({
|
|
93
|
+
title: dto.title,
|
|
94
|
+
description: dto.description ?? null,
|
|
95
|
+
startTime: start,
|
|
96
|
+
endTime: end,
|
|
97
|
+
userId,
|
|
98
|
+
property: dto.property ?? null,
|
|
99
|
+
tags: dto.tags ?? null,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
findAll(userId) {
|
|
103
|
+
return this.repo.findUserEvents(userId);
|
|
104
|
+
}
|
|
105
|
+
findByUserId(userId) {
|
|
106
|
+
return this.repo.findUserEvents(userId);
|
|
107
|
+
}
|
|
108
|
+
async findOne(id, userId) {
|
|
109
|
+
const event = await this.repo.findEvent(id, userId);
|
|
110
|
+
if (!event)
|
|
111
|
+
throw new common_1.NotFoundException("Event not found");
|
|
112
|
+
return event;
|
|
113
|
+
}
|
|
114
|
+
async update(id, dto, userId) {
|
|
115
|
+
const event = await this.findOne(id, userId);
|
|
116
|
+
const data = {};
|
|
117
|
+
if (dto.title !== undefined)
|
|
118
|
+
data.title = dto.title;
|
|
119
|
+
if (dto.description !== undefined)
|
|
120
|
+
data.description = dto.description;
|
|
121
|
+
if (dto.property !== undefined)
|
|
122
|
+
data.property = dto.property;
|
|
123
|
+
if (dto.tags !== undefined)
|
|
124
|
+
data.tags = dto.tags;
|
|
125
|
+
if (dto.startTime)
|
|
126
|
+
data.startTime = new Date(dto.startTime);
|
|
127
|
+
if (dto.endTime)
|
|
128
|
+
data.endTime = new Date(dto.endTime);
|
|
129
|
+
const updated = await this.repo.updateEvent(id, data);
|
|
130
|
+
// 👇 GOOGLE UPDATE
|
|
131
|
+
if (event.googleEventId) {
|
|
132
|
+
const calendar = await this.getGoogleClient(userId);
|
|
133
|
+
await calendar.events.patch({
|
|
134
|
+
calendarId: "primary",
|
|
135
|
+
eventId: event.googleEventId,
|
|
136
|
+
requestBody: {
|
|
137
|
+
summary: updated.title,
|
|
138
|
+
description: updated.description ?? undefined,
|
|
139
|
+
start: {
|
|
140
|
+
dateTime: updated.startTime.toISOString(),
|
|
141
|
+
timeZone: "UTC",
|
|
142
|
+
},
|
|
143
|
+
end: updated.endTime
|
|
144
|
+
? {
|
|
145
|
+
dateTime: updated.endTime.toISOString(),
|
|
146
|
+
timeZone: "UTC",
|
|
147
|
+
}
|
|
148
|
+
: undefined,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return updated;
|
|
153
|
+
}
|
|
154
|
+
async remove(id, userId) {
|
|
155
|
+
const event = await this.findOne(id, userId);
|
|
156
|
+
if (event.googleEventId) {
|
|
157
|
+
const calendar = await this.getGoogleClient(userId);
|
|
158
|
+
await calendar.events.delete({
|
|
159
|
+
calendarId: "primary",
|
|
160
|
+
eventId: event.googleEventId,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return this.repo.deleteEvent(id);
|
|
164
|
+
}
|
|
165
|
+
// ---- Google Sync ----
|
|
166
|
+
defaultEndTime(start) {
|
|
167
|
+
return new Date(start.getTime() + 30 * 60000);
|
|
168
|
+
}
|
|
169
|
+
async syncToGoogle(eventId, userId) {
|
|
170
|
+
const event = await this.repo.findEvent(eventId, userId);
|
|
171
|
+
if (!event)
|
|
172
|
+
throw new common_1.NotFoundException("Event not found");
|
|
173
|
+
const calendar = await this.getGoogleClient(userId);
|
|
174
|
+
const end = event.endTime ?? this.defaultEndTime(event.startTime);
|
|
175
|
+
const result = await calendar.events.insert({
|
|
176
|
+
calendarId: "primary",
|
|
177
|
+
requestBody: {
|
|
178
|
+
summary: event.title,
|
|
179
|
+
description: event.description ?? undefined,
|
|
180
|
+
start: { dateTime: event.startTime.toISOString(), timeZone: "UTC" },
|
|
181
|
+
end: { dateTime: end.toISOString(), timeZone: "UTC" },
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
await this.repo.updateEvent(eventId, {
|
|
185
|
+
googleEventId: result.data.id,
|
|
186
|
+
synced: true,
|
|
187
|
+
});
|
|
188
|
+
return {
|
|
189
|
+
googleEventId: result.data.id,
|
|
190
|
+
htmlLink: result.data.htmlLink,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
async syncAllToGoogle(userId) {
|
|
194
|
+
const events = await this.repo.findUnsyncedEvents(userId);
|
|
195
|
+
const results = [];
|
|
196
|
+
for (const e of events) {
|
|
197
|
+
try {
|
|
198
|
+
const r = await this.syncToGoogle(e.id, userId);
|
|
199
|
+
results.push({ id: e.id, success: true, ...r });
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
results.push({ id: e.id, success: false, error: err.message });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return results;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
exports.CalendarService = CalendarService;
|
|
209
|
+
exports.CalendarService = CalendarService = __decorate([
|
|
210
|
+
(0, common_1.Injectable)(),
|
|
211
|
+
__metadata("design:paramtypes", [calendar_repository_1.CalendarRepository,
|
|
212
|
+
google_oauth_service_1.GoogleOAuthService])
|
|
213
|
+
], CalendarService);
|
|
@@ -0,0 +1,51 @@
|
|
|
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.CreateCalendarDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
class CreateCalendarDto {
|
|
16
|
+
}
|
|
17
|
+
exports.CreateCalendarDto = CreateCalendarDto;
|
|
18
|
+
__decorate([
|
|
19
|
+
(0, swagger_1.ApiProperty)(),
|
|
20
|
+
(0, class_validator_1.IsString)(),
|
|
21
|
+
__metadata("design:type", String)
|
|
22
|
+
], CreateCalendarDto.prototype, "title", void 0);
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
25
|
+
(0, class_validator_1.IsOptional)(),
|
|
26
|
+
(0, class_validator_1.IsString)(),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], CreateCalendarDto.prototype, "description", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, swagger_1.ApiProperty)(),
|
|
31
|
+
(0, class_validator_1.IsDateString)(),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], CreateCalendarDto.prototype, "startTime", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
36
|
+
(0, class_validator_1.IsOptional)(),
|
|
37
|
+
(0, class_validator_1.IsDateString)(),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], CreateCalendarDto.prototype, "endTime", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
42
|
+
(0, class_validator_1.IsOptional)(),
|
|
43
|
+
(0, class_validator_1.IsString)(),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], CreateCalendarDto.prototype, "property", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
48
|
+
(0, class_validator_1.IsOptional)(),
|
|
49
|
+
(0, class_validator_1.IsString)(),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], CreateCalendarDto.prototype, "tags", void 0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UpdateCalendarDto = void 0;
|
|
4
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
5
|
+
const create_calendar_dto_1 = require("./create-calendar.dto");
|
|
6
|
+
class UpdateCalendarDto extends (0, swagger_1.PartialType)(create_calendar_dto_1.CreateCalendarDto) {
|
|
7
|
+
}
|
|
8
|
+
exports.UpdateCalendarDto = UpdateCalendarDto;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EmailFeatureConfig } from "../../email.types";
|
|
2
|
+
export declare class GoogleOAuthService {
|
|
3
|
+
private cfg;
|
|
4
|
+
constructor(cfg: EmailFeatureConfig);
|
|
5
|
+
private redirectUri;
|
|
6
|
+
private oauth;
|
|
7
|
+
/**
|
|
8
|
+
* State should contain userEmail (your controller expects that)
|
|
9
|
+
*/
|
|
10
|
+
getAuthUrl(userEmail: string): string;
|
|
11
|
+
exchangeCode(code: string): Promise<import("google-auth-library").Credentials>;
|
|
12
|
+
createClient(accessToken: string | null, refreshToken: string | null): Promise<import("google-auth-library").OAuth2Client>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GoogleOAuthService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const googleapis_1 = require("googleapis");
|
|
18
|
+
const email_types_1 = require("../../email.types");
|
|
19
|
+
let GoogleOAuthService = class GoogleOAuthService {
|
|
20
|
+
constructor(cfg) {
|
|
21
|
+
this.cfg = cfg;
|
|
22
|
+
}
|
|
23
|
+
redirectUri() {
|
|
24
|
+
return this.cfg.googleCalendarRedirectUri ?? this.cfg.google.redirectUri;
|
|
25
|
+
}
|
|
26
|
+
oauth() {
|
|
27
|
+
return new googleapis_1.google.auth.OAuth2(this.cfg.google.clientId, this.cfg.google.clientSecret, this.redirectUri());
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* State should contain userEmail (your controller expects that)
|
|
31
|
+
*/
|
|
32
|
+
getAuthUrl(userEmail) {
|
|
33
|
+
const state = Buffer.from(JSON.stringify({ userEmail })).toString("base64");
|
|
34
|
+
return this.oauth().generateAuthUrl({
|
|
35
|
+
access_type: "offline",
|
|
36
|
+
prompt: "consent",
|
|
37
|
+
include_granted_scopes: true,
|
|
38
|
+
scope: [
|
|
39
|
+
"https://www.googleapis.com/auth/calendar",
|
|
40
|
+
"https://www.googleapis.com/auth/calendar.events",
|
|
41
|
+
],
|
|
42
|
+
state,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async exchangeCode(code) {
|
|
46
|
+
const { tokens } = await this.oauth().getToken(code);
|
|
47
|
+
return tokens;
|
|
48
|
+
}
|
|
49
|
+
async createClient(accessToken, refreshToken) {
|
|
50
|
+
const client = new googleapis_1.google.auth.OAuth2(this.cfg.google.clientId, this.cfg.google.clientSecret, this.redirectUri());
|
|
51
|
+
client.setCredentials({
|
|
52
|
+
access_token: accessToken || undefined,
|
|
53
|
+
refresh_token: refreshToken || undefined,
|
|
54
|
+
});
|
|
55
|
+
return client;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
exports.GoogleOAuthService = GoogleOAuthService;
|
|
59
|
+
exports.GoogleOAuthService = GoogleOAuthService = __decorate([
|
|
60
|
+
(0, common_1.Injectable)(),
|
|
61
|
+
__param(0, (0, common_1.Inject)(email_types_1.EMAIL_FEATURE_CONFIG)),
|
|
62
|
+
__metadata("design:paramtypes", [Object])
|
|
63
|
+
], GoogleOAuthService);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EmailFeatureConfig } from "../../email.types";
|
|
2
|
+
export declare class GoogleOAuthService {
|
|
3
|
+
private cfg;
|
|
4
|
+
constructor(cfg: EmailFeatureConfig);
|
|
5
|
+
private redirectUri;
|
|
6
|
+
private oauth;
|
|
7
|
+
/**
|
|
8
|
+
* State should contain userEmail (your controller expects that)
|
|
9
|
+
*/
|
|
10
|
+
getAuthUrl(userEmail: string): string;
|
|
11
|
+
exchangeCode(code: string): Promise<import("google-auth-library").Credentials>;
|
|
12
|
+
createClient(accessToken: string | null, refreshToken: string | null): Promise<import("google-auth-library").OAuth2Client>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GoogleOAuthService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const googleapis_1 = require("googleapis");
|
|
18
|
+
const email_types_1 = require("../../email.types");
|
|
19
|
+
let GoogleOAuthService = class GoogleOAuthService {
|
|
20
|
+
constructor(cfg) {
|
|
21
|
+
this.cfg = cfg;
|
|
22
|
+
}
|
|
23
|
+
redirectUri() {
|
|
24
|
+
return this.cfg.googleCalendarRedirectUri ?? this.cfg.google.redirectUri;
|
|
25
|
+
}
|
|
26
|
+
oauth() {
|
|
27
|
+
return new googleapis_1.google.auth.OAuth2(this.cfg.google.clientId, this.cfg.google.clientSecret, this.redirectUri());
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* State should contain userEmail (your controller expects that)
|
|
31
|
+
*/
|
|
32
|
+
getAuthUrl(userEmail) {
|
|
33
|
+
const state = Buffer.from(JSON.stringify({ userEmail })).toString("base64");
|
|
34
|
+
return this.oauth().generateAuthUrl({
|
|
35
|
+
access_type: "offline",
|
|
36
|
+
prompt: "consent",
|
|
37
|
+
include_granted_scopes: true,
|
|
38
|
+
scope: [
|
|
39
|
+
"https://www.googleapis.com/auth/calendar",
|
|
40
|
+
"https://www.googleapis.com/auth/calendar.events",
|
|
41
|
+
],
|
|
42
|
+
state,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async exchangeCode(code) {
|
|
46
|
+
const { tokens } = await this.oauth().getToken(code);
|
|
47
|
+
return tokens;
|
|
48
|
+
}
|
|
49
|
+
async createClient(accessToken, refreshToken) {
|
|
50
|
+
const client = new googleapis_1.google.auth.OAuth2(this.cfg.google.clientId, this.cfg.google.clientSecret, this.redirectUri());
|
|
51
|
+
client.setCredentials({
|
|
52
|
+
access_token: accessToken || undefined,
|
|
53
|
+
refresh_token: refreshToken || undefined,
|
|
54
|
+
});
|
|
55
|
+
return client;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
exports.GoogleOAuthService = GoogleOAuthService;
|
|
59
|
+
exports.GoogleOAuthService = GoogleOAuthService = __decorate([
|
|
60
|
+
(0, common_1.Injectable)(),
|
|
61
|
+
__param(0, (0, common_1.Inject)(email_types_1.EMAIL_FEATURE_CONFIG)),
|
|
62
|
+
__metadata("design:paramtypes", [Object])
|
|
63
|
+
], GoogleOAuthService);
|
|
@@ -0,0 +1,33 @@
|
|
|
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.SendEmailDto = void 0;
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
class SendEmailDto {
|
|
15
|
+
}
|
|
16
|
+
exports.SendEmailDto = SendEmailDto;
|
|
17
|
+
__decorate([
|
|
18
|
+
(0, class_validator_1.IsString)(),
|
|
19
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
20
|
+
__metadata("design:type", String)
|
|
21
|
+
], SendEmailDto.prototype, "accountId", void 0);
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, class_validator_1.IsEmail)(),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], SendEmailDto.prototype, "to", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
__metadata("design:type", String)
|
|
29
|
+
], SendEmailDto.prototype, "subject", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], SendEmailDto.prototype, "body", void 0);
|
|
@@ -0,0 +1,37 @@
|
|
|
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 EmailFeatureModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.EmailFeatureModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const email_types_1 = require("./email.types");
|
|
13
|
+
const email_service_1 = require("./email.service");
|
|
14
|
+
const email_repository_1 = require("./email.repository");
|
|
15
|
+
const google_auth_service_1 = require("./google/google-auth.service");
|
|
16
|
+
const google_gmail_service_1 = require("./google/google-gmail.service");
|
|
17
|
+
let EmailFeatureModule = EmailFeatureModule_1 = class EmailFeatureModule {
|
|
18
|
+
static forRoot(options) {
|
|
19
|
+
return {
|
|
20
|
+
module: EmailFeatureModule_1,
|
|
21
|
+
providers: [
|
|
22
|
+
{ provide: email_types_1.EMAIL_FEATURE_CONFIG, useValue: options.config },
|
|
23
|
+
{ provide: email_types_1.EMAIL_PRISMA, useValue: options.prisma },
|
|
24
|
+
email_service_1.EmailService,
|
|
25
|
+
email_repository_1.EmailRepository,
|
|
26
|
+
google_auth_service_1.GoogleAuthService,
|
|
27
|
+
google_gmail_service_1.GoogleGmailService,
|
|
28
|
+
],
|
|
29
|
+
exports: [email_service_1.EmailService, google_gmail_service_1.GoogleGmailService, email_repository_1.EmailRepository, email_types_1.EMAIL_FEATURE_CONFIG, email_types_1.EMAIL_PRISMA],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.EmailFeatureModule = EmailFeatureModule;
|
|
34
|
+
exports.EmailFeatureModule = EmailFeatureModule = EmailFeatureModule_1 = __decorate([
|
|
35
|
+
(0, common_1.Global)(),
|
|
36
|
+
(0, common_1.Module)({})
|
|
37
|
+
], EmailFeatureModule);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PrismaLike } from "./email.types";
|
|
2
|
+
export declare class EmailRepository {
|
|
3
|
+
private prisma;
|
|
4
|
+
constructor(prisma: PrismaLike);
|
|
5
|
+
listAccounts(userId: string): any;
|
|
6
|
+
findAccount(userId: string, accountId: string): any;
|
|
7
|
+
findByEmail(email: string): any;
|
|
8
|
+
upsertGoogle(userId: string, email: string, data: any): any;
|
|
9
|
+
updateAccount(id: string, data: any): any;
|
|
10
|
+
saveIncoming(userId: string, payload: any): Promise<any>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EmailRepository = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const email_types_1 = require("./email.types");
|
|
18
|
+
let EmailRepository = class EmailRepository {
|
|
19
|
+
constructor(prisma) {
|
|
20
|
+
this.prisma = prisma;
|
|
21
|
+
}
|
|
22
|
+
listAccounts(userId) {
|
|
23
|
+
return this.prisma.emailAccount.findMany({
|
|
24
|
+
where: { userId, status: "CONNECTED" },
|
|
25
|
+
orderBy: { createdAt: "desc" },
|
|
26
|
+
select: { id: true, provider: true, emailAddress: true, status: true, createdAt: true },
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
findAccount(userId, accountId) {
|
|
30
|
+
return this.prisma.emailAccount.findFirst({
|
|
31
|
+
where: { id: accountId, userId },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
findByEmail(email) {
|
|
35
|
+
return this.prisma.emailAccount.findFirst({
|
|
36
|
+
where: { emailAddress: email, provider: "GOOGLE" },
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
upsertGoogle(userId, email, data) {
|
|
40
|
+
return this.prisma.emailAccount.upsert({
|
|
41
|
+
where: {
|
|
42
|
+
provider_emailAddress: {
|
|
43
|
+
provider: "GOOGLE",
|
|
44
|
+
emailAddress: email,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
update: { userId, status: "CONNECTED", ...data },
|
|
48
|
+
create: { userId, provider: "GOOGLE", emailAddress: email, status: "CONNECTED", ...data },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
updateAccount(id, data) {
|
|
52
|
+
return this.prisma.emailAccount.update({ where: { id }, data });
|
|
53
|
+
}
|
|
54
|
+
async saveIncoming(userId, payload) {
|
|
55
|
+
if (!this.prisma.message)
|
|
56
|
+
return null;
|
|
57
|
+
return this.prisma.message.create({
|
|
58
|
+
data: {
|
|
59
|
+
userId,
|
|
60
|
+
channel: "EMAIL",
|
|
61
|
+
status: "PENDING",
|
|
62
|
+
...payload,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.EmailRepository = EmailRepository;
|
|
68
|
+
exports.EmailRepository = EmailRepository = __decorate([
|
|
69
|
+
(0, common_1.Injectable)(),
|
|
70
|
+
__param(0, (0, common_1.Inject)(email_types_1.EMAIL_PRISMA)),
|
|
71
|
+
__metadata("design:paramtypes", [Object])
|
|
72
|
+
], EmailRepository);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GoogleAuthService } from "./google/google-auth.service";
|
|
2
|
+
import { EmailRepository } from "./email.repository";
|
|
3
|
+
export declare class EmailService {
|
|
4
|
+
private auth;
|
|
5
|
+
private repo;
|
|
6
|
+
constructor(auth: GoogleAuthService, repo: EmailRepository);
|
|
7
|
+
connect(userId: string): {
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
callback(userId: string, code: string): Promise<any>;
|
|
11
|
+
accounts(userId: string): any;
|
|
12
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
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.EmailService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const googleapis_1 = require("googleapis");
|
|
15
|
+
const google_auth_service_1 = require("./google/google-auth.service");
|
|
16
|
+
const email_repository_1 = require("./email.repository");
|
|
17
|
+
let EmailService = class EmailService {
|
|
18
|
+
constructor(auth, repo) {
|
|
19
|
+
this.auth = auth;
|
|
20
|
+
this.repo = repo;
|
|
21
|
+
}
|
|
22
|
+
connect(userId) {
|
|
23
|
+
return { url: this.auth.url(userId) };
|
|
24
|
+
}
|
|
25
|
+
async callback(userId, code) {
|
|
26
|
+
const tokens = await this.auth.exchange(code);
|
|
27
|
+
// IMPORTANT
|
|
28
|
+
if (!tokens.access_token || !tokens.refresh_token) {
|
|
29
|
+
throw new Error("Missing tokens from Google. Ensure prompt=consent + access_type=offline. If you authorized before, revoke access and reconnect.");
|
|
30
|
+
}
|
|
31
|
+
const client = this.auth.build(tokens.access_token, tokens.refresh_token);
|
|
32
|
+
const gmail = googleapis_1.google.gmail({ version: "v1", auth: client });
|
|
33
|
+
const profile = await gmail.users.getProfile({ userId: "me" });
|
|
34
|
+
const email = profile.data.emailAddress;
|
|
35
|
+
if (!email)
|
|
36
|
+
throw new Error("Cannot fetch Gmail profile emailAddress");
|
|
37
|
+
return this.repo.upsertGoogle(userId, email, {
|
|
38
|
+
accessToken: tokens.access_token,
|
|
39
|
+
refreshToken: tokens.refresh_token,
|
|
40
|
+
tokenExpiry: tokens.expiry_date ? new Date(tokens.expiry_date) : null,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
accounts(userId) {
|
|
44
|
+
return this.repo.listAccounts(userId);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
exports.EmailService = EmailService;
|
|
48
|
+
exports.EmailService = EmailService = __decorate([
|
|
49
|
+
(0, common_1.Injectable)(),
|
|
50
|
+
__metadata("design:paramtypes", [google_auth_service_1.GoogleAuthService, email_repository_1.EmailRepository])
|
|
51
|
+
], EmailService);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type EmailProvider = "GOOGLE" | "OUTLOOK" | "IMAP";
|
|
2
|
+
export type EmailFeatureConfig = {
|
|
3
|
+
google: {
|
|
4
|
+
clientId: string;
|
|
5
|
+
clientSecret: string;
|
|
6
|
+
/**
|
|
7
|
+
* Email redirect URI (email/google/callback)
|
|
8
|
+
* Example: https://api.domain.com/email/google/callback
|
|
9
|
+
*/
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Optional: Calendar redirect URI (calendar/google/callback)
|
|
14
|
+
* If not provided, falls back to google.redirectUri
|
|
15
|
+
*/
|
|
16
|
+
googleCalendarRedirectUri?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Pub/Sub topic for Gmail watch
|
|
19
|
+
*/
|
|
20
|
+
gmailPubSubTopic?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Optional Outlook OAuth config for calendar
|
|
23
|
+
*/
|
|
24
|
+
outlook?: {
|
|
25
|
+
clientId: string;
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
redirectUri: string;
|
|
28
|
+
tenant?: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export declare const EMAIL_FEATURE_CONFIG: unique symbol;
|
|
32
|
+
export declare const EMAIL_PRISMA: unique symbol;
|
|
33
|
+
export type PrismaLike = {
|
|
34
|
+
emailAccount: {
|
|
35
|
+
findMany: Function;
|
|
36
|
+
findFirst: Function;
|
|
37
|
+
upsert: Function;
|
|
38
|
+
update: Function;
|
|
39
|
+
};
|
|
40
|
+
message?: {
|
|
41
|
+
create: Function;
|
|
42
|
+
};
|
|
43
|
+
user: {
|
|
44
|
+
findUnique: Function;
|
|
45
|
+
update: Function;
|
|
46
|
+
};
|
|
47
|
+
calendarEvent: {
|
|
48
|
+
create: Function;
|
|
49
|
+
findMany: Function;
|
|
50
|
+
findFirst: Function;
|
|
51
|
+
update: Function;
|
|
52
|
+
delete: Function;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/email.types.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.EMAIL_PRISMA = exports.EMAIL_FEATURE_CONFIG = void 0;
|
|
5
|
+
exports.EMAIL_FEATURE_CONFIG = Symbol("EMAIL_FEATURE_CONFIG");
|
|
6
|
+
exports.EMAIL_PRISMA = Symbol("EMAIL_PRISMA");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.body = exports.header = exports.decode = void 0;
|
|
4
|
+
const decode = (s) => Buffer.from(s.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString();
|
|
5
|
+
exports.decode = decode;
|
|
6
|
+
const header = (h = [], n) => h.find((x) => x?.name?.toLowerCase() === n.toLowerCase())?.value;
|
|
7
|
+
exports.header = header;
|
|
8
|
+
const body = (p) => {
|
|
9
|
+
if (p?.body?.data)
|
|
10
|
+
return (0, exports.decode)(p.body.data);
|
|
11
|
+
for (const part of p?.parts ?? []) {
|
|
12
|
+
const r = (0, exports.body)(part);
|
|
13
|
+
if (r)
|
|
14
|
+
return r;
|
|
15
|
+
}
|
|
16
|
+
return "";
|
|
17
|
+
};
|
|
18
|
+
exports.body = body;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Credentials } from "google-auth-library";
|
|
2
|
+
import { EmailFeatureConfig } from "../email.types";
|
|
3
|
+
export declare class GoogleAuthService {
|
|
4
|
+
private cfg;
|
|
5
|
+
constructor(cfg: EmailFeatureConfig);
|
|
6
|
+
private client;
|
|
7
|
+
url(state: string): string;
|
|
8
|
+
exchange(code: string): Promise<Credentials>;
|
|
9
|
+
build(access: string, refresh: string): import("google-auth-library").OAuth2Client;
|
|
10
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GoogleAuthService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const googleapis_1 = require("googleapis");
|
|
18
|
+
const email_types_1 = require("../email.types");
|
|
19
|
+
let GoogleAuthService = class GoogleAuthService {
|
|
20
|
+
constructor(cfg) {
|
|
21
|
+
this.cfg = cfg;
|
|
22
|
+
}
|
|
23
|
+
client() {
|
|
24
|
+
return new googleapis_1.google.auth.OAuth2(this.cfg.google.clientId, this.cfg.google.clientSecret, this.cfg.google.redirectUri);
|
|
25
|
+
}
|
|
26
|
+
url(state) {
|
|
27
|
+
return this.client().generateAuthUrl({
|
|
28
|
+
access_type: "offline",
|
|
29
|
+
prompt: "consent",
|
|
30
|
+
scope: [
|
|
31
|
+
"https://www.googleapis.com/auth/userinfo.email",
|
|
32
|
+
"https://www.googleapis.com/auth/gmail.readonly",
|
|
33
|
+
"https://www.googleapis.com/auth/gmail.send",
|
|
34
|
+
],
|
|
35
|
+
state,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async exchange(code) {
|
|
39
|
+
const { tokens } = await this.client().getToken(code);
|
|
40
|
+
return tokens;
|
|
41
|
+
}
|
|
42
|
+
build(access, refresh) {
|
|
43
|
+
const c = this.client();
|
|
44
|
+
c.setCredentials({ access_token: access, refresh_token: refresh });
|
|
45
|
+
return c;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.GoogleAuthService = GoogleAuthService;
|
|
49
|
+
exports.GoogleAuthService = GoogleAuthService = __decorate([
|
|
50
|
+
(0, common_1.Injectable)(),
|
|
51
|
+
__param(0, (0, common_1.Inject)(email_types_1.EMAIL_FEATURE_CONFIG)),
|
|
52
|
+
__metadata("design:paramtypes", [Object])
|
|
53
|
+
], GoogleAuthService);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EmailRepository } from "../email.repository";
|
|
2
|
+
import { GoogleAuthService } from "./google-auth.service";
|
|
3
|
+
import { EmailFeatureConfig } from "../email.types";
|
|
4
|
+
export declare class GoogleGmailService {
|
|
5
|
+
private repo;
|
|
6
|
+
private auth;
|
|
7
|
+
private cfg;
|
|
8
|
+
constructor(repo: EmailRepository, auth: GoogleAuthService, cfg: EmailFeatureConfig);
|
|
9
|
+
private getClient;
|
|
10
|
+
send(userId: string, accountId: string, to: string, subject: string, text: string): Promise<import("googleapis-common").GaxiosResponseWithHTTP2<import("googleapis").gmail_v1.Schema$Message>>;
|
|
11
|
+
listInbox(userId: string, accountId: string, max?: number, q?: string): Promise<{
|
|
12
|
+
id: string | null | undefined;
|
|
13
|
+
threadId: string | null | undefined;
|
|
14
|
+
subject: any;
|
|
15
|
+
from: any;
|
|
16
|
+
date: any;
|
|
17
|
+
snippet: string | null | undefined;
|
|
18
|
+
}[]>;
|
|
19
|
+
getSingle(userId: string, accountId: string, messageId: string): Promise<{
|
|
20
|
+
id: string | null | undefined;
|
|
21
|
+
threadId: string | null | undefined;
|
|
22
|
+
subject: any;
|
|
23
|
+
from: any;
|
|
24
|
+
to: any;
|
|
25
|
+
date: any;
|
|
26
|
+
snippet: string | null | undefined;
|
|
27
|
+
body: string;
|
|
28
|
+
}>;
|
|
29
|
+
watch(userId: string, accountId: string, topicName?: string): Promise<import("googleapis").gmail_v1.Schema$WatchResponse>;
|
|
30
|
+
sync(email: string, historyId: string): Promise<void>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GoogleGmailService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const googleapis_1 = require("googleapis");
|
|
18
|
+
const email_repository_1 = require("../email.repository");
|
|
19
|
+
const google_auth_service_1 = require("./google-auth.service");
|
|
20
|
+
const gmail_parser_1 = require("./gmail-parser");
|
|
21
|
+
const email_types_1 = require("../email.types");
|
|
22
|
+
let GoogleGmailService = class GoogleGmailService {
|
|
23
|
+
constructor(repo, auth, cfg) {
|
|
24
|
+
this.repo = repo;
|
|
25
|
+
this.auth = auth;
|
|
26
|
+
this.cfg = cfg;
|
|
27
|
+
}
|
|
28
|
+
async getClient(userId, accountId) {
|
|
29
|
+
const acc = await this.repo.findAccount(userId, accountId);
|
|
30
|
+
if (!acc)
|
|
31
|
+
throw new common_1.NotFoundException("Email account not found");
|
|
32
|
+
if (!acc.accessToken || !acc.refreshToken)
|
|
33
|
+
throw new common_1.NotFoundException("Tokens missing");
|
|
34
|
+
const authClient = this.auth.build(acc.accessToken, acc.refreshToken);
|
|
35
|
+
const gmail = googleapis_1.google.gmail({ version: "v1", auth: authClient });
|
|
36
|
+
return { gmail, acc };
|
|
37
|
+
}
|
|
38
|
+
async send(userId, accountId, to, subject, text) {
|
|
39
|
+
const { gmail } = await this.getClient(userId, accountId);
|
|
40
|
+
const raw = Buffer.from(`To:${to}\r\nSubject:${subject}\r\n\r\n${text}`)
|
|
41
|
+
.toString("base64")
|
|
42
|
+
.replace(/\+/g, "-")
|
|
43
|
+
.replace(/\//g, "_")
|
|
44
|
+
.replace(/=+$/, "");
|
|
45
|
+
return gmail.users.messages.send({ userId: "me", requestBody: { raw } });
|
|
46
|
+
}
|
|
47
|
+
async listInbox(userId, accountId, max = 20, q) {
|
|
48
|
+
const { gmail } = await this.getClient(userId, accountId);
|
|
49
|
+
const list = await gmail.users.messages.list({
|
|
50
|
+
userId: "me",
|
|
51
|
+
labelIds: ["INBOX"],
|
|
52
|
+
maxResults: max,
|
|
53
|
+
q,
|
|
54
|
+
});
|
|
55
|
+
const ids = list.data.messages?.map((m) => m.id).filter(Boolean) ?? [];
|
|
56
|
+
if (!ids.length)
|
|
57
|
+
return [];
|
|
58
|
+
const messages = await Promise.all(ids.map((id) => gmail.users.messages.get({
|
|
59
|
+
userId: "me",
|
|
60
|
+
id,
|
|
61
|
+
format: "metadata",
|
|
62
|
+
metadataHeaders: ["Subject", "From", "Date"],
|
|
63
|
+
})));
|
|
64
|
+
return messages.map((m) => {
|
|
65
|
+
const headers = m.data.payload?.headers ?? [];
|
|
66
|
+
return {
|
|
67
|
+
id: m.data.id,
|
|
68
|
+
threadId: m.data.threadId,
|
|
69
|
+
subject: (0, gmail_parser_1.header)(headers, "Subject"),
|
|
70
|
+
from: (0, gmail_parser_1.header)(headers, "From"),
|
|
71
|
+
date: (0, gmail_parser_1.header)(headers, "Date"),
|
|
72
|
+
snippet: m.data.snippet,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async getSingle(userId, accountId, messageId) {
|
|
77
|
+
if (!messageId)
|
|
78
|
+
throw new common_1.NotFoundException("messageId is required");
|
|
79
|
+
const { gmail } = await this.getClient(userId, accountId);
|
|
80
|
+
const msg = await gmail.users.messages.get({
|
|
81
|
+
userId: "me",
|
|
82
|
+
id: messageId,
|
|
83
|
+
format: "full",
|
|
84
|
+
});
|
|
85
|
+
const payload = msg.data.payload;
|
|
86
|
+
const headers = payload?.headers ?? [];
|
|
87
|
+
return {
|
|
88
|
+
id: msg.data.id,
|
|
89
|
+
threadId: msg.data.threadId,
|
|
90
|
+
subject: (0, gmail_parser_1.header)(headers, "Subject"),
|
|
91
|
+
from: (0, gmail_parser_1.header)(headers, "From"),
|
|
92
|
+
to: (0, gmail_parser_1.header)(headers, "To"),
|
|
93
|
+
date: (0, gmail_parser_1.header)(headers, "Date"),
|
|
94
|
+
snippet: msg.data.snippet,
|
|
95
|
+
body: payload ? (0, gmail_parser_1.body)(payload) : "",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async watch(userId, accountId, topicName) {
|
|
99
|
+
const { gmail, acc } = await this.getClient(userId, accountId);
|
|
100
|
+
const realTopic = topicName ?? this.cfg.gmailPubSubTopic;
|
|
101
|
+
if (!realTopic)
|
|
102
|
+
throw new Error("Missing GMAIL Pub/Sub topicName");
|
|
103
|
+
const r = await gmail.users.watch({
|
|
104
|
+
userId: "me",
|
|
105
|
+
requestBody: { topicName: realTopic },
|
|
106
|
+
});
|
|
107
|
+
await this.repo.updateAccount(acc.id, {
|
|
108
|
+
lastHistoryId: r.data.historyId ?? null,
|
|
109
|
+
watchExpiration: r.data.expiration ? new Date(Number(r.data.expiration)) : null,
|
|
110
|
+
});
|
|
111
|
+
return r.data;
|
|
112
|
+
}
|
|
113
|
+
async sync(email, historyId) {
|
|
114
|
+
const acc = await this.repo.findByEmail(email);
|
|
115
|
+
if (!acc || !acc.accessToken || !acc.refreshToken)
|
|
116
|
+
return;
|
|
117
|
+
const authClient = this.auth.build(acc.accessToken, acc.refreshToken);
|
|
118
|
+
const gmail = googleapis_1.google.gmail({ version: "v1", auth: authClient });
|
|
119
|
+
// first time: store only
|
|
120
|
+
if (!acc.lastHistoryId) {
|
|
121
|
+
await this.repo.updateAccount(acc.id, { lastHistoryId: historyId });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const h = await gmail.users.history.list({
|
|
125
|
+
userId: "me",
|
|
126
|
+
startHistoryId: acc.lastHistoryId ?? undefined,
|
|
127
|
+
});
|
|
128
|
+
for (const x of h.data.history ?? []) {
|
|
129
|
+
for (const m of x.messagesAdded ?? []) {
|
|
130
|
+
if (!m.message?.id)
|
|
131
|
+
continue;
|
|
132
|
+
const g = await gmail.users.messages.get({
|
|
133
|
+
userId: "me",
|
|
134
|
+
id: m.message.id,
|
|
135
|
+
format: "full",
|
|
136
|
+
});
|
|
137
|
+
const payload = g.data.payload;
|
|
138
|
+
const headers = payload?.headers ?? [];
|
|
139
|
+
await this.repo.saveIncoming(acc.userId, {
|
|
140
|
+
subject: (0, gmail_parser_1.header)(headers, "Subject"),
|
|
141
|
+
fromAddress: (0, gmail_parser_1.header)(headers, "From"),
|
|
142
|
+
toAddress: (0, gmail_parser_1.header)(headers, "To"),
|
|
143
|
+
body: payload ? (0, gmail_parser_1.body)(payload) : "",
|
|
144
|
+
meta: { gmailId: m.message.id },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
await this.repo.updateAccount(acc.id, { lastHistoryId: historyId });
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
exports.GoogleGmailService = GoogleGmailService;
|
|
152
|
+
exports.GoogleGmailService = GoogleGmailService = __decorate([
|
|
153
|
+
(0, common_1.Injectable)(),
|
|
154
|
+
__param(2, (0, common_1.Inject)(email_types_1.EMAIL_FEATURE_CONFIG)),
|
|
155
|
+
__metadata("design:paramtypes", [email_repository_1.EmailRepository,
|
|
156
|
+
google_auth_service_1.GoogleAuthService, Object])
|
|
157
|
+
], GoogleGmailService);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./email-feature.module";
|
|
2
|
+
export * from "./email.service";
|
|
3
|
+
export * from "./email.repository";
|
|
4
|
+
export * from "./google/google-gmail.service";
|
|
5
|
+
export * from "./dto/send-email.dto";
|
|
6
|
+
export * from "./calendar/calendar-feature.module";
|
|
7
|
+
export * from "./calendar/calendar.service";
|
|
8
|
+
export * from "./calendar/dto/create-calendar.dto";
|
|
9
|
+
export * from "./calendar/dto/update-calendar.dto";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
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("./email-feature.module"), exports);
|
|
18
|
+
__exportStar(require("./email.service"), exports);
|
|
19
|
+
__exportStar(require("./email.repository"), exports);
|
|
20
|
+
__exportStar(require("./google/google-gmail.service"), exports);
|
|
21
|
+
__exportStar(require("./dto/send-email.dto"), exports);
|
|
22
|
+
__exportStar(require("./calendar/calendar-feature.module"), exports);
|
|
23
|
+
__exportStar(require("./calendar/calendar.service"), exports);
|
|
24
|
+
__exportStar(require("./calendar/dto/create-calendar.dto"), exports);
|
|
25
|
+
__exportStar(require("./calendar/dto/update-calendar.dto"), exports);
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nestjs-mailbridge",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "rimraf dist && tsc -p tsconfig.json"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@nestjs/common": "^11.1.0",
|
|
14
|
+
"@nestjs/swagger": "^11.2.6",
|
|
15
|
+
"class-transformer": "^0.5.1",
|
|
16
|
+
"class-validator": "^0.14.3",
|
|
17
|
+
"google-auth-library": "^10.5.0",
|
|
18
|
+
"googleapis": "^171.4.0",
|
|
19
|
+
"swagger-ui-express": "^5.0.1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^25.3.0",
|
|
23
|
+
"rimraf": "^6.1.3",
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
}
|
|
26
|
+
}
|