@checkfirst/nestjs-outlook 8.0.2 → 8.0.3
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/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/config/outlook-config.interface.d.ts +10 -0
- package/dist/interfaces/state/redis-like.interface.d.ts +13 -0
- package/dist/interfaces/state/redis-like.interface.js +3 -0
- package/dist/interfaces/state/redis-like.interface.js.map +1 -0
- package/dist/microsoft-outlook.module.js +63 -0
- package/dist/microsoft-outlook.module.js.map +1 -1
- package/dist/services/auth/microsoft-auth.service.d.ts +5 -1
- package/dist/services/auth/microsoft-auth.service.js +13 -4
- package/dist/services/auth/microsoft-auth.service.js.map +1 -1
- package/dist/services/calendar/calendar.service.d.ts +1 -1
- package/dist/services/calendar/calendar.service.js +4 -4
- package/dist/services/calendar/calendar.service.js.map +1 -1
- package/dist/services/shared/delta-sync.service.d.ts +6 -1
- package/dist/services/shared/delta-sync.service.js +121 -110
- package/dist/services/shared/delta-sync.service.js.map +1 -1
- package/dist/services/shared/graph-rate-limiter.service.d.ts +15 -17
- package/dist/services/shared/graph-rate-limiter.service.js +104 -148
- package/dist/services/shared/graph-rate-limiter.service.js.map +1 -1
- package/dist/services/shared/outlook-lock.store.d.ts +37 -0
- package/dist/services/shared/outlook-lock.store.js +134 -0
- package/dist/services/shared/outlook-lock.store.js.map +1 -0
- package/dist/services/shared/outlook-rate-limit.store.d.ts +59 -0
- package/dist/services/shared/outlook-rate-limit.store.js +235 -0
- package/dist/services/shared/outlook-rate-limit.store.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/outlook-api-executor.util.js +3 -3
- package/dist/utils/outlook-api-executor.util.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { RedisLike } from "../../interfaces/state/redis-like.interface";
|
|
2
|
+
export type RateLimitWindowKey = "sec" | "min10";
|
|
3
|
+
export type CircuitBreakerState = "closed" | "open" | "half-open";
|
|
4
|
+
export interface CircuitBreakerSnapshot {
|
|
5
|
+
state: CircuitBreakerState;
|
|
6
|
+
openedAt: number | null;
|
|
7
|
+
}
|
|
8
|
+
export interface OutlookRateLimitStore {
|
|
9
|
+
readonly kind: "memory" | "redis";
|
|
10
|
+
recordRequest(userId: string, windowMs: number, key: RateLimitWindowKey): Promise<number>;
|
|
11
|
+
getCount(userId: string, windowMs: number, key: RateLimitWindowKey): Promise<number>;
|
|
12
|
+
getCooldown(userId: string): Promise<number | null>;
|
|
13
|
+
setCooldown(userId: string, untilMs: number): Promise<void>;
|
|
14
|
+
getCbState(): Promise<CircuitBreakerSnapshot | null>;
|
|
15
|
+
setCbState(snapshot: CircuitBreakerSnapshot): Promise<void>;
|
|
16
|
+
tryClaimHalfOpenProbe(ttlMs: number): Promise<boolean>;
|
|
17
|
+
getActiveUserCount(): Promise<number>;
|
|
18
|
+
cleanupInactive(thresholdMs: number): Promise<number>;
|
|
19
|
+
}
|
|
20
|
+
export declare class InMemoryOutlookRateLimitStore implements OutlookRateLimitStore {
|
|
21
|
+
readonly kind: "memory";
|
|
22
|
+
private readonly logger;
|
|
23
|
+
private readonly users;
|
|
24
|
+
private cbState;
|
|
25
|
+
private halfOpenProbeUntil;
|
|
26
|
+
private getOrCreate;
|
|
27
|
+
private trim;
|
|
28
|
+
recordRequest(userId: string, windowMs: number, key: RateLimitWindowKey): Promise<number>;
|
|
29
|
+
getCount(userId: string, windowMs: number, key: RateLimitWindowKey): Promise<number>;
|
|
30
|
+
getCooldown(userId: string): Promise<number | null>;
|
|
31
|
+
setCooldown(userId: string, untilMs: number): Promise<void>;
|
|
32
|
+
getCbState(): Promise<CircuitBreakerSnapshot | null>;
|
|
33
|
+
setCbState(snapshot: CircuitBreakerSnapshot): Promise<void>;
|
|
34
|
+
tryClaimHalfOpenProbe(ttlMs: number): Promise<boolean>;
|
|
35
|
+
getActiveUserCount(): Promise<number>;
|
|
36
|
+
cleanupInactive(thresholdMs: number): Promise<number>;
|
|
37
|
+
}
|
|
38
|
+
export declare class RedisOutlookRateLimitStore implements OutlookRateLimitStore {
|
|
39
|
+
private readonly redis;
|
|
40
|
+
private readonly keyPrefix;
|
|
41
|
+
readonly kind: "redis";
|
|
42
|
+
private readonly logger;
|
|
43
|
+
private memberCounter;
|
|
44
|
+
constructor(redis: RedisLike, keyPrefix: string);
|
|
45
|
+
private rlKey;
|
|
46
|
+
private cdKey;
|
|
47
|
+
private cbKey;
|
|
48
|
+
private cbProbeKey;
|
|
49
|
+
private uniqueMember;
|
|
50
|
+
recordRequest(userId: string, windowMs: number, key: RateLimitWindowKey): Promise<number>;
|
|
51
|
+
getCount(userId: string, windowMs: number, key: RateLimitWindowKey): Promise<number>;
|
|
52
|
+
getCooldown(userId: string): Promise<number | null>;
|
|
53
|
+
setCooldown(userId: string, untilMs: number): Promise<void>;
|
|
54
|
+
getCbState(): Promise<CircuitBreakerSnapshot | null>;
|
|
55
|
+
setCbState(snapshot: CircuitBreakerSnapshot): Promise<void>;
|
|
56
|
+
tryClaimHalfOpenProbe(ttlMs: number): Promise<boolean>;
|
|
57
|
+
getActiveUserCount(): Promise<number>;
|
|
58
|
+
cleanupInactive(_thresholdMs: number): Promise<number>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisOutlookRateLimitStore = exports.InMemoryOutlookRateLimitStore = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class InMemoryOutlookRateLimitStore {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.kind = "memory";
|
|
8
|
+
this.logger = new common_1.Logger(InMemoryOutlookRateLimitStore.name);
|
|
9
|
+
this.users = new Map();
|
|
10
|
+
this.cbState = {
|
|
11
|
+
state: "closed",
|
|
12
|
+
openedAt: null,
|
|
13
|
+
};
|
|
14
|
+
this.halfOpenProbeUntil = 0;
|
|
15
|
+
}
|
|
16
|
+
getOrCreate(userId) {
|
|
17
|
+
let s = this.users.get(userId);
|
|
18
|
+
if (!s) {
|
|
19
|
+
s = {
|
|
20
|
+
windows: new Map(),
|
|
21
|
+
cooldownUntil: null,
|
|
22
|
+
lastActivity: Date.now(),
|
|
23
|
+
};
|
|
24
|
+
this.users.set(userId, s);
|
|
25
|
+
}
|
|
26
|
+
return s;
|
|
27
|
+
}
|
|
28
|
+
trim(arr, cutoff) {
|
|
29
|
+
let i = 0;
|
|
30
|
+
while (i < arr.length && arr[i] < cutoff)
|
|
31
|
+
i++;
|
|
32
|
+
return i === 0 ? arr : arr.slice(i);
|
|
33
|
+
}
|
|
34
|
+
recordRequest(userId, windowMs, key) {
|
|
35
|
+
var _a;
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
const s = this.getOrCreate(userId);
|
|
38
|
+
s.lastActivity = now;
|
|
39
|
+
const arr = (_a = s.windows.get(key)) !== null && _a !== void 0 ? _a : [];
|
|
40
|
+
const trimmed = this.trim(arr, now - windowMs);
|
|
41
|
+
trimmed.push(now);
|
|
42
|
+
s.windows.set(key, trimmed);
|
|
43
|
+
return Promise.resolve(trimmed.length);
|
|
44
|
+
}
|
|
45
|
+
getCount(userId, windowMs, key) {
|
|
46
|
+
const s = this.users.get(userId);
|
|
47
|
+
if (!s)
|
|
48
|
+
return Promise.resolve(0);
|
|
49
|
+
const arr = s.windows.get(key);
|
|
50
|
+
if (!arr)
|
|
51
|
+
return Promise.resolve(0);
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
const trimmed = this.trim(arr, now - windowMs);
|
|
54
|
+
s.windows.set(key, trimmed);
|
|
55
|
+
return Promise.resolve(trimmed.length);
|
|
56
|
+
}
|
|
57
|
+
getCooldown(userId) {
|
|
58
|
+
const s = this.users.get(userId);
|
|
59
|
+
if (!s || s.cooldownUntil === null)
|
|
60
|
+
return Promise.resolve(null);
|
|
61
|
+
if (s.cooldownUntil <= Date.now()) {
|
|
62
|
+
s.cooldownUntil = null;
|
|
63
|
+
return Promise.resolve(null);
|
|
64
|
+
}
|
|
65
|
+
return Promise.resolve(s.cooldownUntil);
|
|
66
|
+
}
|
|
67
|
+
setCooldown(userId, untilMs) {
|
|
68
|
+
const s = this.getOrCreate(userId);
|
|
69
|
+
s.cooldownUntil = untilMs;
|
|
70
|
+
s.lastActivity = Date.now();
|
|
71
|
+
return Promise.resolve();
|
|
72
|
+
}
|
|
73
|
+
getCbState() {
|
|
74
|
+
return Promise.resolve(Object.assign({}, this.cbState));
|
|
75
|
+
}
|
|
76
|
+
setCbState(snapshot) {
|
|
77
|
+
this.cbState = Object.assign({}, snapshot);
|
|
78
|
+
return Promise.resolve();
|
|
79
|
+
}
|
|
80
|
+
tryClaimHalfOpenProbe(ttlMs) {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
if (this.halfOpenProbeUntil > now)
|
|
83
|
+
return Promise.resolve(false);
|
|
84
|
+
this.halfOpenProbeUntil = now + ttlMs;
|
|
85
|
+
return Promise.resolve(true);
|
|
86
|
+
}
|
|
87
|
+
getActiveUserCount() {
|
|
88
|
+
return Promise.resolve(this.users.size);
|
|
89
|
+
}
|
|
90
|
+
cleanupInactive(thresholdMs) {
|
|
91
|
+
const now = Date.now();
|
|
92
|
+
let removed = 0;
|
|
93
|
+
for (const [userId, state] of this.users.entries()) {
|
|
94
|
+
if (now - state.lastActivity > thresholdMs) {
|
|
95
|
+
this.users.delete(userId);
|
|
96
|
+
removed++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return Promise.resolve(removed);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.InMemoryOutlookRateLimitStore = InMemoryOutlookRateLimitStore;
|
|
103
|
+
const RECORD_LUA = `
|
|
104
|
+
local key = KEYS[1]
|
|
105
|
+
local now = tonumber(ARGV[1])
|
|
106
|
+
local windowMs = tonumber(ARGV[2])
|
|
107
|
+
local ttlMs = tonumber(ARGV[3])
|
|
108
|
+
local member = ARGV[4]
|
|
109
|
+
redis.call('ZREMRANGEBYSCORE', key, '-inf', now - windowMs)
|
|
110
|
+
redis.call('ZADD', key, now, member)
|
|
111
|
+
redis.call('PEXPIRE', key, ttlMs)
|
|
112
|
+
return redis.call('ZCARD', key)
|
|
113
|
+
`;
|
|
114
|
+
const COUNT_LUA = `
|
|
115
|
+
local key = KEYS[1]
|
|
116
|
+
local now = tonumber(ARGV[1])
|
|
117
|
+
local windowMs = tonumber(ARGV[2])
|
|
118
|
+
redis.call('ZREMRANGEBYSCORE', key, '-inf', now - windowMs)
|
|
119
|
+
return redis.call('ZCARD', key)
|
|
120
|
+
`;
|
|
121
|
+
class RedisOutlookRateLimitStore {
|
|
122
|
+
constructor(redis, keyPrefix) {
|
|
123
|
+
this.redis = redis;
|
|
124
|
+
this.keyPrefix = keyPrefix;
|
|
125
|
+
this.kind = "redis";
|
|
126
|
+
this.logger = new common_1.Logger(RedisOutlookRateLimitStore.name);
|
|
127
|
+
this.memberCounter = 0;
|
|
128
|
+
}
|
|
129
|
+
rlKey(userId, key) {
|
|
130
|
+
return `${this.keyPrefix}rl:${userId}:${key}`;
|
|
131
|
+
}
|
|
132
|
+
cdKey(userId) {
|
|
133
|
+
return `${this.keyPrefix}cd:${userId}`;
|
|
134
|
+
}
|
|
135
|
+
cbKey() {
|
|
136
|
+
return `${this.keyPrefix}cb`;
|
|
137
|
+
}
|
|
138
|
+
cbProbeKey() {
|
|
139
|
+
return `${this.keyPrefix}cb:probe`;
|
|
140
|
+
}
|
|
141
|
+
uniqueMember() {
|
|
142
|
+
this.memberCounter = (this.memberCounter + 1) % 1000000;
|
|
143
|
+
return `${Date.now()}-${process.pid}-${this.memberCounter}`;
|
|
144
|
+
}
|
|
145
|
+
async recordRequest(userId, windowMs, key) {
|
|
146
|
+
try {
|
|
147
|
+
const now = Date.now();
|
|
148
|
+
const ttlMs = windowMs + 60000;
|
|
149
|
+
const result = await this.redis.eval(RECORD_LUA, 1, this.rlKey(userId, key), now, windowMs, ttlMs, this.uniqueMember());
|
|
150
|
+
return typeof result === "number" ? result : Number(result);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
this.logger.error(`[recordRequest] Redis error for ${userId}/${key}: ${err instanceof Error ? err.message : String(err)}`);
|
|
154
|
+
return Number.POSITIVE_INFINITY;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async getCount(userId, windowMs, key) {
|
|
158
|
+
try {
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
const result = await this.redis.eval(COUNT_LUA, 1, this.rlKey(userId, key), now, windowMs);
|
|
161
|
+
return typeof result === "number" ? result : Number(result);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
this.logger.error(`[getCount] Redis error for ${userId}/${key}: ${err instanceof Error ? err.message : String(err)}`);
|
|
165
|
+
return Number.POSITIVE_INFINITY;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async getCooldown(userId) {
|
|
169
|
+
try {
|
|
170
|
+
const v = await this.redis.get(this.cdKey(userId));
|
|
171
|
+
if (!v)
|
|
172
|
+
return null;
|
|
173
|
+
const until = Number(v);
|
|
174
|
+
if (!Number.isFinite(until) || until <= Date.now())
|
|
175
|
+
return null;
|
|
176
|
+
return until;
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
this.logger.error(`[getCooldown] Redis error for ${userId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async setCooldown(userId, untilMs) {
|
|
184
|
+
try {
|
|
185
|
+
const ttl = Math.max(1, untilMs - Date.now());
|
|
186
|
+
await this.redis.set(this.cdKey(userId), String(untilMs), "PX", ttl);
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
this.logger.error(`[setCooldown] Redis error for ${userId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async getCbState() {
|
|
193
|
+
var _a;
|
|
194
|
+
try {
|
|
195
|
+
const hash = (await this.redis.hgetall(this.cbKey()));
|
|
196
|
+
if (!hash || Object.keys(hash).length === 0) {
|
|
197
|
+
return { state: "closed", openedAt: null };
|
|
198
|
+
}
|
|
199
|
+
const state = (_a = hash.state) !== null && _a !== void 0 ? _a : "closed";
|
|
200
|
+
const openedAtRaw = hash.openedAt;
|
|
201
|
+
const openedAt = openedAtRaw && openedAtRaw !== "null" ? Number(openedAtRaw) : null;
|
|
202
|
+
return { state, openedAt: Number.isFinite(openedAt) ? openedAt : null };
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
this.logger.error(`[getCbState] Redis error: ${err instanceof Error ? err.message : String(err)}`);
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async setCbState(snapshot) {
|
|
210
|
+
try {
|
|
211
|
+
await this.redis.hset(this.cbKey(), "state", snapshot.state, "openedAt", snapshot.openedAt === null ? "null" : String(snapshot.openedAt));
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
this.logger.error(`[setCbState] Redis error: ${err instanceof Error ? err.message : String(err)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async tryClaimHalfOpenProbe(ttlMs) {
|
|
218
|
+
try {
|
|
219
|
+
const result = await this.redis.set(this.cbProbeKey(), "1", "PX", ttlMs, "NX");
|
|
220
|
+
return result === "OK";
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
this.logger.error(`[tryClaimHalfOpenProbe] Redis error: ${err instanceof Error ? err.message : String(err)}`);
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
getActiveUserCount() {
|
|
228
|
+
return Promise.resolve(0);
|
|
229
|
+
}
|
|
230
|
+
cleanupInactive(_thresholdMs) {
|
|
231
|
+
return Promise.resolve(0);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
exports.RedisOutlookRateLimitStore = RedisOutlookRateLimitStore;
|
|
235
|
+
//# sourceMappingURL=outlook-rate-limit.store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outlook-rate-limit.store.js","sourceRoot":"","sources":["../../../src/services/shared/outlook-rate-limit.store.ts"],"names":[],"mappings":"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"}
|