Add HTTPS server (self-signed fallback), update frontend messages, and README
This commit is contained in:
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Voice Translator App
|
||||||
|
|
||||||
|
This app provides text translation, speech-to-text, and text-to-speech functionality. It runs an Express server and serves a single-page frontend.
|
||||||
|
|
||||||
|
HTTPS for microphone access
|
||||||
|
---------------------------------
|
||||||
|
Modern browsers require a secure context (HTTPS or localhost over HTTPS) for getUserMedia microphone access. This project can start an HTTPS server on `https://localhost:3443` using either your own certificate files or a generated self-signed certificate.
|
||||||
|
|
||||||
|
How to run
|
||||||
|
-----------
|
||||||
|
1. Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/chadee/Ria
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start the server (HTTP + HTTPS):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
This starts the HTTP server on `http://localhost:3000` and an HTTPS server on `https://localhost:3443`.
|
||||||
|
|
||||||
|
Using your own certificate
|
||||||
|
--------------------------
|
||||||
|
If you have SSL certificate and key files, set the following environment variables before starting the server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export SSL_CERT_PATH=/path/to/cert.pem
|
||||||
|
export SSL_KEY_PATH=/path/to/key.pem
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
When no certificate is provided, the server generates a temporary self-signed certificate at runtime and serves HTTPS on `https://localhost:3443`.
|
||||||
|
|
||||||
|
Accepting the self-signed cert warning
|
||||||
|
------------------------------------
|
||||||
|
When using the generated self-signed certificate, your browser will show a security warning. To proceed:
|
||||||
|
|
||||||
|
- In Chrome/Edge/Brave: Click "Advanced" → "Proceed to localhost (unsafe)".
|
||||||
|
- In Firefox: Accept the risk and continue.
|
||||||
|
- In Safari: Go to System Settings → Privacy & Security → Certificates to trust the localhost certificate if needed.
|
||||||
|
|
||||||
|
After accepting the warning, open `https://localhost:3443` and allow microphone access when prompted. The site will run in a secure context and `getUserMedia` will work.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
- The server will log a warning when generating a temporary self-signed certificate.
|
||||||
|
- For production deployments use valid CA-signed certificates.
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
"google-tts-api": "^2.0.1"
|
"google-tts-api": "^2.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"puppeteer": "^25.3.0"
|
"puppeteer": "^25.3.0",
|
||||||
|
"selfsigned": "^2.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,9 @@ async function checkMicrophonePermission() {
|
|||||||
|
|
||||||
if (status.state === 'denied') {
|
if (status.state === 'denied') {
|
||||||
if (microphoneHint) {
|
if (microphoneHint) {
|
||||||
microphoneHint.innerHTML = '🔒 Microphone blocked for this site. To allow:\n• Click the lock icon in the address bar → Site settings → Microphone → Allow\n• Or open this app via http://localhost:3000 and re-grant permissions.'
|
// If the page was loaded over HTTP (not secure), recommend using HTTPS localhost:3443
|
||||||
|
const suggestedUrl = (location.protocol === 'http:') ? 'https://localhost:3443' : 'http://localhost:3000';
|
||||||
|
microphoneHint.innerHTML = `🔒 Microphone blocked for this site. To allow:\n• Click the lock icon in the address bar → Site settings → Microphone → Allow\n• Or open this app via ${suggestedUrl} and re-grant permissions.`
|
||||||
.replace(/\n/g, '<br>');
|
.replace(/\n/g, '<br>');
|
||||||
microphoneHint.style.display = 'block';
|
microphoneHint.style.display = 'block';
|
||||||
}
|
}
|
||||||
@@ -224,7 +226,8 @@ async function verifyServerReachability() {
|
|||||||
throw new Error(`HTTP ${response.status}`);
|
throw new Error(`HTTP ${response.status}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Server reachability check failed:', error);
|
console.error('Server reachability check failed:', error);
|
||||||
showStatus('Cannot reach the app server. Open the app via http://localhost:3000', 'error');
|
const openUrl = (location.protocol === 'http:') ? 'https://localhost:3443' : 'http://localhost:3000';
|
||||||
|
showStatus(`Cannot reach the app server. Open the app via ${openUrl}`, 'error');
|
||||||
logDev(`Server reachability failed: ${error?.message || error}`);
|
logDev(`Server reachability failed: ${error?.message || error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
server.js
34
server.js
@@ -57,6 +57,30 @@ const m2m100LangMap = {
|
|||||||
const app = express();
|
const app = express();
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
|
|
||||||
|
// HTTPS setup (optional). Serve HTTPS on 3443 using provided certs or generate a self-signed cert.
|
||||||
|
const https = require('https');
|
||||||
|
const fs = require('fs');
|
||||||
|
const selfsigned = require('selfsigned');
|
||||||
|
const SSL_PORT = process.env.SSL_PORT || 3443;
|
||||||
|
|
||||||
|
function loadSslOptions() {
|
||||||
|
const keyPath = process.env.SSL_KEY_PATH;
|
||||||
|
const certPath = process.env.SSL_CERT_PATH;
|
||||||
|
|
||||||
|
if (keyPath && certPath && fs.existsSync(keyPath) && fs.existsSync(certPath)) {
|
||||||
|
return {
|
||||||
|
key: fs.readFileSync(keyPath),
|
||||||
|
cert: fs.readFileSync(certPath)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a temporary self-signed certificate for localhost
|
||||||
|
console.warn('No SSL cert/key provided. Generating a temporary self-signed certificate for https://localhost:' + SSL_PORT);
|
||||||
|
const attrs = [{ name: 'commonName', value: 'localhost' }];
|
||||||
|
const pems = selfsigned.generate(attrs, { days: 365 });
|
||||||
|
return { key: pems.private, cert: pems.cert };
|
||||||
|
}
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.use(bodyParser.json({ limit: '10mb' }));
|
app.use(bodyParser.json({ limit: '10mb' }));
|
||||||
@@ -478,3 +502,13 @@ app.listen(PORT, () => {
|
|||||||
========================================
|
========================================
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Start HTTPS server on SSL_PORT
|
||||||
|
try {
|
||||||
|
const sslOptions = loadSslOptions();
|
||||||
|
https.createServer(sslOptions, app).listen(SSL_PORT, () => {
|
||||||
|
console.log(`HTTPS server running on: https://localhost:${SSL_PORT}`);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to start HTTPS server:', err);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user