mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-11 01:36:16 +00:00
feature: adding account management and point loading from sessions
This commit is contained in:
@@ -1 +0,0 @@
|
||||
<!-- This is a placeholder. The actual favicon will be served from /assets/logo.png -->
|
||||
119
src/dashboard/SessionLoader.ts
Normal file
119
src/dashboard/SessionLoader.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export interface SessionPoints {
|
||||
email: string
|
||||
points: number
|
||||
lastUpdated: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load points from session data
|
||||
*/
|
||||
export function loadPointsFromSessions(email: string): number | undefined {
|
||||
try {
|
||||
const sessionsDir = path.join(process.cwd(), 'sessions')
|
||||
if (!fs.existsSync(sessionsDir)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Try to find session file for this email
|
||||
const emailHash = Buffer.from(email).toString('base64').replace(/[^a-zA-Z0-9]/g, '')
|
||||
const possibleFiles = [
|
||||
`${email}.json`,
|
||||
`${emailHash}.json`,
|
||||
`session_${email}.json`
|
||||
]
|
||||
|
||||
for (const filename of possibleFiles) {
|
||||
const filepath = path.join(sessionsDir, filename)
|
||||
if (fs.existsSync(filepath)) {
|
||||
const data = JSON.parse(fs.readFileSync(filepath, 'utf-8'))
|
||||
if (data.points !== undefined) {
|
||||
return data.points
|
||||
}
|
||||
if (data.availablePoints !== undefined) {
|
||||
return data.availablePoints
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined
|
||||
} catch (error) {
|
||||
console.error(`[Dashboard] Error loading points for ${email}:`, error)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load all points from sessions
|
||||
*/
|
||||
export function loadAllPointsFromSessions(): Map<string, number> {
|
||||
const pointsMap = new Map<string, number>()
|
||||
|
||||
try {
|
||||
const sessionsDir = path.join(process.cwd(), 'sessions')
|
||||
if (!fs.existsSync(sessionsDir)) {
|
||||
return pointsMap
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(sessionsDir)
|
||||
|
||||
for (const filename of files) {
|
||||
if (!filename.endsWith('.json')) continue
|
||||
|
||||
try {
|
||||
const filepath = path.join(sessionsDir, filename)
|
||||
const data = JSON.parse(fs.readFileSync(filepath, 'utf-8'))
|
||||
|
||||
const email = data.email || data.account?.email
|
||||
const points = data.points || data.availablePoints
|
||||
|
||||
if (email && points !== undefined) {
|
||||
pointsMap.set(email, points)
|
||||
}
|
||||
} catch (error) {
|
||||
// Skip invalid files
|
||||
continue
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Dashboard] Error loading points from sessions:', error)
|
||||
}
|
||||
|
||||
return pointsMap
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load points from job state
|
||||
*/
|
||||
export function loadPointsFromJobState(email: string): number | undefined {
|
||||
try {
|
||||
const jobStateDir = path.join(process.cwd(), 'sessions', 'job-state')
|
||||
if (!fs.existsSync(jobStateDir)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(jobStateDir)
|
||||
|
||||
for (const filename of files) {
|
||||
if (!filename.endsWith('.json')) continue
|
||||
|
||||
try {
|
||||
const filepath = path.join(jobStateDir, filename)
|
||||
const data = JSON.parse(fs.readFileSync(filepath, 'utf-8'))
|
||||
|
||||
if (data.email === email || data.account === email) {
|
||||
return data.points || data.availablePoints
|
||||
}
|
||||
} catch (error) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return undefined
|
||||
} catch (error) {
|
||||
console.error(`[Dashboard] Error loading job state for ${email}:`, error)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,19 @@ export const apiRouter = Router()
|
||||
// GET /api/status - Bot status
|
||||
apiRouter.get('/status', (_req: Request, res: Response) => {
|
||||
try {
|
||||
const status = dashboardState.getStatus()
|
||||
res.json(status)
|
||||
const accounts = dashboardState.getAccounts()
|
||||
|
||||
// If no accounts loaded yet, try to load them
|
||||
if (accounts.length === 0) {
|
||||
try {
|
||||
const loadedAccounts = loadAccounts()
|
||||
dashboardState.initializeAccounts(loadedAccounts.map(a => a.email))
|
||||
} catch (error) {
|
||||
console.error('[Dashboard] Failed to load accounts for status:', error)
|
||||
}
|
||||
}
|
||||
|
||||
res.json(dashboardState.getStatus())
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' })
|
||||
}
|
||||
@@ -20,7 +31,19 @@ apiRouter.get('/status', (_req: Request, res: Response) => {
|
||||
// GET /api/accounts - List all accounts with masked emails
|
||||
apiRouter.get('/accounts', (_req: Request, res: Response) => {
|
||||
try {
|
||||
const accounts = dashboardState.getAccounts()
|
||||
let accounts = dashboardState.getAccounts()
|
||||
|
||||
// If no accounts in state, try to load from config
|
||||
if (accounts.length === 0) {
|
||||
try {
|
||||
const loadedAccounts = loadAccounts()
|
||||
dashboardState.initializeAccounts(loadedAccounts.map(a => a.email))
|
||||
accounts = dashboardState.getAccounts()
|
||||
} catch (error) {
|
||||
console.error('[Dashboard] Failed to load accounts:', error)
|
||||
}
|
||||
}
|
||||
|
||||
res.json(accounts)
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' })
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { MicrosoftRewardsBot } from '../index'
|
||||
import { loadAllPointsFromSessions, loadPointsFromJobState } from './SessionLoader'
|
||||
|
||||
export interface DashboardStatus {
|
||||
running: boolean
|
||||
@@ -133,12 +134,23 @@ class DashboardState {
|
||||
|
||||
// Initialize accounts from config
|
||||
public initializeAccounts(emails: string[]): void {
|
||||
// Load points from sessions if available
|
||||
const pointsMap = loadAllPointsFromSessions()
|
||||
|
||||
for (const email of emails) {
|
||||
if (!this.accounts.has(email)) {
|
||||
// Try to get points from session or job state
|
||||
let points = pointsMap.get(email)
|
||||
if (points === undefined) {
|
||||
points = loadPointsFromJobState(email)
|
||||
}
|
||||
|
||||
this.accounts.set(email, {
|
||||
email,
|
||||
maskedEmail: this.maskEmail(email),
|
||||
status: 'idle'
|
||||
status: 'idle',
|
||||
points: points,
|
||||
lastSync: points !== undefined ? new Date().toISOString() : undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user