Browse Source

Resolve problem with creating a VAPID at initial startup

pull/1/head
Matthew Raymer 1 year ago
parent
commit
a278897127
  1. BIN
      push_server
  2. 57
      src/db.ts
  3. 32
      src/main.ts
  4. 2
      src/notificationService.ts
  5. 1
      src/subscriptionService.ts
  6. 45
      src/vapidService.ts

BIN
push_server

Binary file not shown.

57
src/db.ts

@ -1,29 +1,30 @@
import { DataSource, Repository } from "typeorm"; import { DataSource } from "typeorm";
import { Subscription } from './Subscription.js' import { Subscription } from './Subscription.js'
import { VapidKeys } from './VapidKeys.js'; import { VapidKeys } from './VapidKeys.js';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
class DBService { class DBService {
private static instance: DBService; private static instance: DBService;
private dataSource: DataSource; private dataSource: DataSource;
private subscriptionRepository: Repository<Subscription>;
private vapidRepository: Repository<VapidKeys>;
public isReady = false; public isReady = false;
private constructor() { private constructor() {
console.log("DBService constructor");
this.dataSource = new DataSource({ this.dataSource = new DataSource({
type: "sqlite", type: "sqlite",
database: "push_server", database: "push_server",
entities: [VapidKeys, Subscription] entities: [VapidKeys, Subscription],
synchronize: true
}); });
this.dataSource.initialize().then(()=>{ this.dataSource.initialize().then(()=>{
console.log("Initialized"); console.log("Initialized");
this.subscriptionRepository = this.dataSource.getRepository(Subscription);
this.vapidRepository = this.dataSource.getRepository(VapidKeys);
this.isReady = true; this.isReady = true;
}).catch((err)=>{console.error(err);}); }).catch((err)=>{
console.error(err);
});
} }
@ -45,27 +46,45 @@ class DBService {
async getSubscriptions(): Promise<Subscription[]> { async getSubscriptions(): Promise<Subscription[]> {
return await this.subscriptionRepository.find(); let result = [ new Subscription ];
if (this.isReady) {
result = await this.dataSource.manager.find(Subscription);
} else {
console.log(__filename, "Database not ready.")
}
return result;
} }
async getVapidKeys(): Promise<VapidKeys[]> { async getVapidKeys(): Promise<VapidKeys[]> {
console.log(__filename, "getVapidKeys", this.isReady);
let result = [ new VapidKeys() ]; let result = [ new VapidKeys() ];
if ( this.vapidRepository && this.isReady) { if ( this.isReady ) {
result = await this.vapidRepository.find(); result = await this.dataSource.manager.find(VapidKeys);
console.log(__filename, "results of find: ", result);
} else { } else {
console.log("vapidRepository is null or db is not ready"); console.log(__filename, "Database is not ready");
} }
return result return result;
} }
async saveVapidKeys(publicKey: string, privateKey: string) { async saveVapidKeys(publicKey: string, privateKey: string): Promise<VapidKeys> {
const vapidkeys = new VapidKeys(); let result = new VapidKeys();
vapidkeys.privateKey = privateKey; result.privateKey = privateKey;
vapidkeys.publicKey = publicKey; result.publicKey = publicKey;
return await this.dataSource.manager.save(vapidkeys); if ( this.isReady ) {
result = await this.dataSource.manager.save(result);
} else {
console.log(__filename, "Database is not ready.");
}
return result;
} }
} }
export default DBService; export default DBService;

32
src/main.ts

@ -1,7 +1,9 @@
import SubscriptionService from './subscriptionService.js'; import SubscriptionService from './subscriptionService.js';
import { Message, NotificationService } from './notificationService.js'; import { Message, NotificationService } from './notificationService.js';
import { VapidKeys } from './VapidKeys.js'; import { VapidKeys } from './VapidKeys.js';
import VapidService from './vapidService.js'; import VapidService from './vapidService.js';
import DBService from './db.js';
import express, { Express, Request, Response } from 'express'; import express, { Express, Request, Response } from 'express';
@ -26,7 +28,8 @@ class Server {
private worker?: Worker; private worker?: Worker;
private subscriptionService: SubscriptionService = SubscriptionService.getInstance(); private subscriptionService: SubscriptionService = SubscriptionService.getInstance();
private notificationService: NotificationService; private notificationService: NotificationService;
private vapidService: VapidService = VapidService.getInstance(); dbService: DBService = DBService.getInstance();
vapidService: VapidService = VapidService.getInstance();
private message: Message; private message: Message;
constructor(port: number) { constructor(port: number) {
@ -48,9 +51,10 @@ class Server {
}); });
this.app.get('/vapid', async (_: Request, res: Response) => { this.app.get('/vapid', async (_: Request, res: Response) => {
const vapidkeys: VapidKeys = await this.vapidService.getVapidKeys()[0]; const vapidkeys: VapidKeys[] = await this.vapidService.getVapidKeys();
console.log(vapidkeys); const vapidkey = vapidkeys[0];
res.send({});
res.send({"vapidKey": vapidkey['publicKey']});
}); });
} }
@ -61,7 +65,7 @@ class Server {
this.worker = new Worker(workerPath, { workerData: 'world' }); this.worker = new Worker(workerPath, { workerData: 'world' });
this.worker.on('message', (message) => { this.worker.on('message', (message) => {
console.log(`Received message from worker: ${message} @ ${new Date()}`); console.log(message);
this.message = { "title": "Check TimeSafari"} as Message; this.message = { "title": "Check TimeSafari"} as Message;
this.notificationService.broadcast(this.message); this.notificationService.broadcast(this.message);
}); });
@ -96,7 +100,25 @@ class Server {
} }
} }
// Initialize and start the server // Initialize and start the server
const server = new Server(3000); const server = new Server(3000);
const executeAsyncFunction = async () => {
const keys: VapidKeys[] = await server.vapidService.getVapidKeys();
if (keys.length === 0) {
await server.vapidService.createVAPIDKeys();
}
};
setTimeout(() => {
executeAsyncFunction().catch(error => {
// Handle any errors here
console.error('An error occurred:', error);
});
}, 5000); // Execute after a delay of 5 seconds
server.start(); server.start();

2
src/notificationService.ts

@ -18,8 +18,6 @@ export class NotificationService {
private vapidService: VapidService = VapidService.getInstance(); private vapidService: VapidService = VapidService.getInstance();
constructor() { constructor() {
console.log("NotificationService constructor");
} }
private generateSalt(length = 16): Buffer { private generateSalt(length = 16): Buffer {

1
src/subscriptionService.ts

@ -14,7 +14,6 @@ class SubscriptionService {
private dbService: DBService = DBService.getInstance(); private dbService: DBService = DBService.getInstance();
private constructor() { private constructor() {
console.log("SubscriptionService constructor");
} }

45
src/vapidService.ts

@ -3,6 +3,9 @@ import { VapidKeys } from './VapidKeys.js';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import crypto from 'crypto'; import crypto from 'crypto';
import DBService from './db.js'; import DBService from './db.js';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
export interface VapidKeyData { export interface VapidKeyData {
publicKey: string; publicKey: string;
@ -13,14 +16,8 @@ class VapidService {
private static instance: VapidService; private static instance: VapidService;
private dbService: DBService = DBService.getInstance(); private dbService: DBService = DBService.getInstance();
private constructor() { private constructor() {
if (this.dbService.isReady) {
const keys = this.generateVAPIDKeys();
this.addVapidKeys(keys);
} else {
console.log("Not ready.");
}
} }
@ -32,6 +29,20 @@ class VapidService {
} }
public async createVAPIDKeys(): Promise<VapidKeys> {
let result = new VapidKeys();
if ( this.dbService.isReady ) {
const keys = this.generateVAPIDKeys();
await this.dbService.saveVapidKeys(keys['publicKey'], keys['privateKey']);
} else {
console.log(__filename, "Database is not ready.");
}
return result;
}
private generateVAPIDKeys(): VapidKeyData { private generateVAPIDKeys(): VapidKeyData {
const ecdh = crypto.createECDH('prime256v1'); const ecdh = crypto.createECDH('prime256v1');
ecdh.generateKeys(); ecdh.generateKeys();
@ -39,22 +50,24 @@ class VapidService {
publicKey: ecdh.getPublicKey().toString('base64'), publicKey: ecdh.getPublicKey().toString('base64'),
privateKey: ecdh.getPrivateKey().toString('base64') privateKey: ecdh.getPrivateKey().toString('base64')
}; };
console.log(result);
return result; return result;
} }
/*
private async addVapidKeys(vapidkeys: VapidKeyData) { private async addVapidKeys(vapidkeys: VapidKeyData): Promise<VapidKeys> {
let result = new VapidKeys();
const keys = await this.getVapidKeys(); const keys = await this.getVapidKeys();
console.log(keys);
if (keys.length == 1 && typeof(keys[0].publicKey) == "undefined" ) { if (keys.length == 1 && typeof(keys[0].publicKey) == "undefined" ) {
this.dbService.saveVapidKeys(vapidkeys.publicKey, vapidkeys.privateKey); result = await this.dbService.saveVapidKeys(vapidkeys.publicKey, vapidkeys.privateKey);
} }
return result;
} }
*/
async getVapidKeys(): Promise<VapidKeys[]> { async getVapidKeys(): Promise<VapidKeys[]> {
return this.dbService.getVapidKeys(); let result = await this.dbService.getVapidKeys();
return result;
} }
@ -76,4 +89,8 @@ class VapidService {
} }
} }
(async ()=> {
})();
export default VapidService; export default VapidService;
Loading…
Cancel
Save