diff --git a/src/services/NotificationService.ts b/src/services/NotificationService.ts index b47fff0..982028b 100644 --- a/src/services/NotificationService.ts +++ b/src/services/NotificationService.ts @@ -1,4 +1,7 @@ import { GetterRepository } from "../repositories/GetterRepository"; +import * as crypto from "node:crypto"; +import jwt from "jsonwebtoken"; +import * as fs from "node:fs"; interface ScheduledNotificationData { deviceId: string; @@ -7,8 +10,46 @@ interface ScheduledNotificationData { } export class NotificationService { + private token: string | undefined = undefined; + private lastRefreshedTimeMs: number | undefined = undefined; + constructor(private repository: GetterRepository) {} + private encryptionKey = crypto.randomBytes(32); + private iv = crypto.randomBytes(16); + + public async reloadAPNsTokenIfTimePassed() { + if (this.lastReloadedTimeForAPNsIsTooRecent()) { + return; + } + + const keyId = process.env.APNS_KEY_ID; + const teamId = process.env.APNS_TEAM_ID; + const privateKeyPath = process.env.APNS_KEY_PATH; + if (!privateKeyPath) return; + const privateKey = fs.readFileSync(privateKeyPath); + + const tokenHeader = { + alg: "ES256", + "kid": keyId, + }; + + const claimsPayload = { + "iss": teamId, + "iat": Date.now(), + }; + + this.token = jwt.sign(claimsPayload, privateKey, { + algorithm: "ES256", + header: tokenHeader + }); + } + + private lastReloadedTimeForAPNsIsTooRecent() { + const thirtyMinutesMs = 1800000; + return this.lastRefreshedTimeMs && Date.now() - this.lastRefreshedTimeMs < thirtyMinutesMs; + } + public async scheduleNotification({ deviceId, shuttleId, stopId }: ScheduledNotificationData) { }