HEX
Server: nginx/1.28.1
System: Linux 10-41-63-61 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User: www (1001)
PHP: 7.4.33
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/oura.mlazu.com/20260313/server.ts
import express from 'express';
import { createServer as createViteServer } from 'vite';
import path from 'path';
import axios from 'axios';
import dotenv from 'dotenv';

dotenv.config();

async function startServer() {
  const app = express();
  const PORT = 3000;

  app.use(express.json());

  // Hardcoded Oura PAT for direct access
  const OURA_PAT = "BZH3BQQWD4XINFO3Y7AW7O2HXKHLFEZH";

  // API Routes
  app.get('/api/user/status', (req, res) => {
    res.json({ 
      connected: true,
      isPat: true
    });
  });

  app.get('/api/oura/data', async (req, res) => {
    const token = OURA_PAT;

    try {
      const today = new Date().toISOString().split('T')[0];
      const sevenDaysAgo = new Date(Date.now() - 7 * 86400000).toISOString().split('T')[0];

      // Fetch readiness, sleep summary, sleep periods, and activity for the last 7 days
      const [readiness, dailySleep, sleepPeriods, activity] = await Promise.all([
        axios.get(`https://api.ouraring.com/v2/usercollection/daily_readiness?start_date=${sevenDaysAgo}&end_date=${today}`, {
          headers: { Authorization: `Bearer ${token}` }
        }),
        axios.get(`https://api.ouraring.com/v2/usercollection/daily_sleep?start_date=${sevenDaysAgo}&end_date=${today}`, {
          headers: { Authorization: `Bearer ${token}` }
        }),
        axios.get(`https://api.ouraring.com/v2/usercollection/sleep?start_date=${sevenDaysAgo}&end_date=${today}`, {
          headers: { Authorization: `Bearer ${token}` }
        }),
        axios.get(`https://api.ouraring.com/v2/usercollection/daily_activity?start_date=${sevenDaysAgo}&end_date=${today}`, {
          headers: { Authorization: `Bearer ${token}` }
        })
      ]);

      // Merge sleep period data (like average_hrv) into daily sleep summary efficiently
      const periodMap = new Map(sleepPeriods.data.data.map((p: any) => [p.day, p]));
      const mergedSleep = dailySleep.data.data.map((ds: any) => {
        const period = periodMap.get(ds.day) || {};
        return { ...(ds as object), ...(period as object) };
      });

      res.json({
        readiness: readiness.data.data,
        sleep: mergedSleep,
        activity: activity.data.data
      });
    } catch (error: any) {
      console.error('Oura API Error:', error.response?.data || error.message);
      res.status(500).json({ error: 'Failed to fetch Oura data' });
    }
  });

  app.post('/api/auth/logout', (req, res) => {
    res.json({ success: true });
  });

  // Vite middleware for development
  if (process.env.NODE_ENV !== 'production') {
    const vite = await createViteServer({
      server: { middlewareMode: true },
      appType: 'spa',
    });
    app.use(vite.middlewares);
  } else {
    const distPath = path.join(process.cwd(), 'dist');
    app.use(express.static(distPath));
    app.get('*', (req, res) => {
      res.sendFile(path.join(distPath, 'index.html'));
    });
  }

  app.listen(PORT, '0.0.0.0', () => {
    console.log(`Server running on http://localhost:${PORT}`);
  });
}

startServer();