From 4916f8efbfc1477d409add1039640221fd6ba4b8 Mon Sep 17 00:00:00 2001 From: Kristine Jones Date: Mon, 13 Mar 2023 20:58:05 +0000 Subject: [PATCH] feat(iCloud): Send notifications to user! --- package.json | 4 +-- src/Library/iCloud.ts | 57 ++++++++++++++++++++++++++++++- src/Modules/User/index.ts | 27 +++++++++++++-- src/index.ts | 71 ++++++++++++++++++--------------------- 4 files changed, 116 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 3efe5ac..37eadbf 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,11 @@ "test": "ts-estest ./src", "prepublishOnly": "npm run build", "build": "tsc -p ./tsconfig.build.json", - "start:debug": "node --loader @k-foss/ts-esnode --experimental-modules --experimental-specifier-resolution=node --harmony-top-level-await ./", + "start:debug": "node --loader @k-foss/ts-esnode --experimental-modules --experimental-specifier-resolution=node ./", "dev": "nodemon", "prettier": "prettier --config .prettierrc --check \"src/**/*ts\"", "lint": "eslint ./src --ext .js,.ts", - "runBin": "node --loader @k-foss/ts-esnode --experimental-modules --experimental-specifier-resolution=node --harmony-top-level-await ./src/Utils/runScript.ts" + "runBin": "node --loader @k-foss/ts-esnode --experimental-modules --experimental-specifier-resolution=node ./src/Utils/runScript.ts" }, "devDependencies": { "@k-foss/ts-esnode": "^2.0.3", diff --git a/src/Library/iCloud.ts b/src/Library/iCloud.ts index 273702f..7177e53 100644 --- a/src/Library/iCloud.ts +++ b/src/Library/iCloud.ts @@ -1,9 +1,64 @@ // src/Library/iCloud.ts import iCloud from 'icloudjs'; import { CONFIG } from './Config'; +import got from 'got'; +import { logger, LogMode } from './Logger'; +import readline from 'readline/promises'; + export const iCloudAPI = new iCloud({ ...CONFIG.iCloud, trustDevice: true, - saveCredentials: true, }); + +export async function initiCloud(): Promise { + logger.log(LogMode.INFO, `Logging into iCloud`); + + await iCloudAPI.authenticate(); + + logger.log(LogMode.DEBUG, `iCloud Status`, iCloudAPI.status); + + if (iCloudAPI.status === 'MfaRequested') { + logger.log(LogMode.WARN, `iCloud needs multifactor`); + + const consoleInterface = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + const mfaCode = await consoleInterface.question('Please provide MFA code\n'); + logger.log(LogMode.DEBUG, `Receieved code ${mfaCode}`); + + logger.log(LogMode.INFO, `Providing MFA to iCloud`); + await iCloudAPI.provideMfaCode(mfaCode); + } + + await iCloudAPI.awaitReady; +} + +export async function sendAlert(device: string, { + subject = 'Find My iPhone Alert', + text = 'Hello World!' +}): Promise { + if (iCloudAPI.accountInfo) { + const { findme: { url: prefixUrl } } = iCloudAPI.accountInfo.webservices + + logger.log(LogMode.INFO, `Attempting to send alert`, prefixUrl) + + const api = got.extend({ + headers: iCloudAPI.authStore.getHeaders(), + }) + + return api.post(`${prefixUrl}/fmipservice/client/web/sendMessage`, { + json: { + device, + subject, + sounds: true, + userText: true, + text + } + }) + } else { + throw new Error('iCloud Not Connected') + } +} \ No newline at end of file diff --git a/src/Modules/User/index.ts b/src/Modules/User/index.ts index ef71723..9a6c812 100644 --- a/src/Modules/User/index.ts +++ b/src/Modules/User/index.ts @@ -1,13 +1,36 @@ // src/Modules/User/index.ts +import { iCloudAPI, sendAlert } from "../../Library/iCloud"; +import { logger, LogMode } from "../../Library/Logger"; export class User { public name: string; + public deviceID: string; + + + public async findUserNotifyDevice(deviceName: string): Promise { + const findMyAPI = iCloudAPI.getService('findme'); + + await findMyAPI.refresh() + + for (const [deviceID, device] of findMyAPI.devices) { + logger.log(LogMode.DEBUG, `Looping over user Devices`, deviceID, device); + + if (device.deviceInfo.name === deviceName) { + logger.log(LogMode.DEBUG, `Found device ${deviceName} with the ID of ${deviceID}`); + + this.deviceID = deviceID; + } + } + } /** * Sends notification to user via her Apple Watch Ultra */ - public async notifyUser() { - + public async notifyUser(options: { + subject?: string, + text?: string + }) { + await sendAlert(this.deviceID, options) } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 072776a..cdc45a0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,35 +1,30 @@ // src/index.ts import 'reflect-metadata'; import { CONFIG } from './Library/Config'; -import { iCloudAPI } from './Library/iCloud'; +import { initiCloud } from './Library/iCloud'; import { logger, LogMode } from './Library/Logger'; import { GoTransit } from './Modules/GoTransit'; +import { User } from './Modules/User'; import { sayHello } from './Utils/sayHello'; -import readline from 'readline/promises'; -logger.log(LogMode.INFO, `Starting TransitRouting`); -logger.log(LogMode.INFO, `Logging into iCloud`); +logger.log(LogMode.INFO, `Starting TransitRouting`); -await iCloudAPI.authenticate(); -logger.log(LogMode.INFO, `iCloud Status`, iCloudAPI.status); +logger.log(LogMode.INFO, `Init iCloud Library`); +await initiCloud(); -if (iCloudAPI.status === 'MfaRequested') { - logger.log(LogMode.INFO, `iCloud needs multifactor`); +logger.log(LogMode.INFO, `Creating Kristine Entity`); - const consoleInterface = readline.createInterface({ - input: process.stdin, - output: process.stdout, - }); +const kristine = new User(); - const mfaCode = await consoleInterface.question('Please provide MFA code'); - logger.log(LogMode.DEBUG, `Receieved code ${mfaCode}`); +await kristine.findUserNotifyDevice(`Kristine’s Apple Watch`); - logger.log(LogMode.INFO, `Providing MFA to iCloud`); - await iCloudAPI.provideMfaCode(mfaCode); -} +await kristine.notifyUser({ + subject: 'Platform Assignment', + text: 'Platform 6 & 7' +}) const goAPI = new GoTransit({ apiURL: CONFIG.apiURL, @@ -39,27 +34,27 @@ const goAPI = new GoTransit({ logger.log(LogMode.INFO, `Making request`); -const unionDepartures = await goAPI.unionDepartures(); - -for (const departure of unionDepartures) { - if (departure.Service === 'Kitchener') { - if (departure.Platform !== '-') { - logger.log( - LogMode.DEBUG, - `Union Departure to Kitchener at platform`, - departure.Platform, - ); - } - } -} - -const trains = await goAPI.getAllTrains(); - -for (const train of trains) { - if (train.LineCode === 'GT') { - logger.log(LogMode.DEBUG, `Trains`, train); - } -} +// const unionDepartures = await goAPI.unionDepartures(); + +// for (const departure of unionDepartures) { +// if (departure.Service === 'Kitchener') { +// if (departure.Platform !== '-') { +// logger.log( +// LogMode.DEBUG, +// `Union Departure to Kitchener at platform`, +// departure.Platform, +// ); +// } +// } +// } + +// const trains = await goAPI.getAllTrains(); + +// for (const train of trains) { +// if (train.LineCode === 'GT') { +// logger.log(LogMode.DEBUG, `Trains`, train); +// } +// } await sayHello('K-FOSS');