Skip to content

Commit ad85026

Browse files
Getting rid of Endpoint (#2732)
* Get rid of Endpoint and ExpectationService * Migrate user-protected endpoints to eggspress * eggspress better typedefs
1 parent cea40b3 commit ad85026

36 files changed

Lines changed: 1401 additions & 1720 deletions

src/backend/src/ExtensionService.js

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
*/
1919

2020
const { AdvancedBase } = require('@heyputer/putility');
21+
const eggspress = require('./api/eggspress');
2122
const BaseService = require('./services/BaseService');
22-
const { Endpoint } = require('./util/expressutil');
2323
const configurable_auth = require('./middleware/configurable_auth');
2424
const { Context } = require('./util/context');
2525
const { DB_WRITE } = require('./services/database/consts');
@@ -58,16 +58,14 @@ class ExtensionServiceState extends AdvancedBase {
5858
mw.push(configurable_auth(auth_conf));
5959
}
6060

61-
const endpoint = Endpoint({
62-
methods: options.methods ?? ['GET'],
61+
const router = eggspress(path, {
62+
allowedMethods: options.methods ?? ['GET'],
6363
mw,
64-
route: path,
65-
handler: handler,
6664
...(options.subdomain ? { subdomain: options.subdomain } : {}),
6765
otherOpts: options.otherOpts || {},
68-
});
66+
}, handler);
6967

70-
this.expressThings_.push({ type: 'endpoint', value: endpoint });
68+
this.expressThings_.push({ type: 'router', value: [router] });
7169
}
7270
}
7371

@@ -181,10 +179,6 @@ class ExtensionService extends BaseService {
181179

182180
'__on_install.routes' (_, { app }) {
183181
for ( const thing of this.state.expressThings_ ) {
184-
if ( thing.type === 'endpoint' ) {
185-
thing.value.attach(app);
186-
continue;
187-
}
188182
if ( thing.type === 'router' ) {
189183
app.use(...thing.value);
190184
continue;

src/backend/src/filesystem/batch/BatchExecutor.js

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ const APIError = require('../../api/APIError');
2323
const { Context } = require('../../util/context');
2424
const config = require('../../config');
2525
const { TeePromise } = require('@heyputer/putility').libs.promise;
26-
const { WorkUnit } = require('../../modules/core/lib/expect');
27-
2826
class BatchExecutor extends AdvancedBase {
2927
static LOG_LEVEL = true;
3028

@@ -33,7 +31,6 @@ class BatchExecutor extends AdvancedBase {
3331
this.x = x;
3432
this.actor = actor;
3533
this.pathResolver = new PathResolver({ actor });
36-
this.expectations = x.get('services').get('expectations');
3734
this.log = log;
3835
this.errors = errors;
3936
this.responsePromises = [];
@@ -64,19 +61,12 @@ class BatchExecutor extends AdvancedBase {
6461

6562
this.concurrent_ops++;
6663

67-
const { expectations } = this;
6864
const command_cls = commands[op.op];
6965
if ( this.log_batchCommands ) {
7066
console.log(command_cls, JSON.stringify(op, null, 2));
7167
}
7268
delete op.op;
7369

74-
const workUnit = WorkUnit.create();
75-
expectations.expect_eventually({
76-
workUnit,
77-
checkpoint: 'operation responded',
78-
});
79-
8070
// TEMP: event service will handle this
8171
op.original_client_socket_id = req.body.original_client_socket_id;
8272
op.socket_id = req.body.socket_id;
@@ -93,22 +83,13 @@ class BatchExecutor extends AdvancedBase {
9383
});
9484
}
9585

96-
if ( file ) {
97-
workUnit.checkpoint(`about to run << ${
98-
file.originalname ?? file.name
99-
} >> ${
100-
JSON.stringify(op)}`);
101-
}
10286
const command_ins = await command_cls.run({
10387
getFile: () => file,
10488
pathResolver: this.pathResolver,
10589
actor: this.actor,
10690
}, op);
107-
workUnit.checkpoint('operation invoked');
10891

10992
const res = await command_ins.awaitValue('result');
110-
// const res = await opctx.awaitValue('response');
111-
workUnit.checkpoint('operation responded');
11293
return res;
11394
} catch (e) {
11495
this.hasError = true;

src/backend/src/modules/apps/AppIconService.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { NodePathSelector } from '../../filesystem/node/selectors.js';
2727
import { get_app } from '../../helpers.js';
2828
import BaseService from '../../services/BaseService.js';
2929
import { DB_READ, DB_WRITE } from '../../services/database/consts.js';
30-
import { Endpoint } from '../../util/expressutil.js';
30+
import eggspress from '../../api/eggspress.js';
3131
import { buffer_to_stream, stream_to_buffer } from '../../util/streamutil.js';
3232
import { AppRedisCacheSpace } from './AppRedisCacheSpace.js';
3333
import DEFAULT_APP_ICON from './default-app-icon.js';
@@ -106,16 +106,12 @@ export class AppIconService extends BaseService {
106106
stream.pipe(res);
107107
};
108108

109-
Endpoint({
110-
route: '/app-icon/:app_uid',
111-
methods: ['GET'],
112-
handler,
113-
}).attach(app);
114-
Endpoint({
115-
route: '/app-icon/:app_uid/:size',
116-
methods: ['GET'],
117-
handler,
118-
}).attach(app);
109+
app.use(eggspress('/app-icon/:app_uid', {
110+
allowedMethods: ['GET'],
111+
}, handler));
112+
app.use(eggspress('/app-icon/:app_uid/:size', {
113+
allowedMethods: ['GET'],
114+
}, handler));
119115
}
120116

121117
getSizes () {

src/backend/src/modules/broadcast/BroadcastService.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import { createHmac, randomUUID, timingSafeEqual } from 'crypto';
2020
import { Agent as HttpsAgent } from 'https';
2121
import axios from 'axios';
2222
import { redisClient } from '../../clients/redis/redisSingleton.js';
23+
import eggspress from '../../api/eggspress.js';
2324
import { BaseService } from '../../services/BaseService.js';
2425
import { Context } from '../../util/context.js';
25-
import { Endpoint } from '../../util/expressutil.js';
2626

2727
export class BroadcastService extends BaseService {
2828
#peersByKey = {};
@@ -348,12 +348,9 @@ export class BroadcastService extends BaseService {
348348
const svc_web = this.services.get('web-server');
349349
svc_web.allow_undefined_origin('/broadcast/webhook');
350350

351-
// TODO DS: stop using Endpoint
352-
Endpoint({
353-
route: '/broadcast/webhook',
354-
methods: ['POST'],
355-
handler: this.#handleWebhookRequest.bind(this),
356-
}).attach(app);
351+
app.use(eggspress('/broadcast/webhook', {
352+
allowedMethods: ['POST'],
353+
}, this.#handleWebhookRequest.bind(this)));
357354
}
358355

359356
async #handleWebhookRequest (req, res) {

src/backend/src/modules/captcha/services/CaptchaService.js

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919

2020
const BaseService = require('../../../services/BaseService');
21-
const { Endpoint } = require('../../../util/expressutil');
21+
const eggspress = require('../../../api/eggspress');
2222
const { checkCaptcha } = require('../middleware/captcha-middleware');
2323

2424
/**
@@ -129,36 +129,32 @@ class CaptchaService extends BaseService {
129129
app.use('/api/captcha', api);
130130

131131
// Generate captcha endpoint
132-
Endpoint({
133-
route: '/generate',
134-
methods: ['GET'],
135-
handler: async (req, res) => {
136-
const captcha = this.generateCaptcha();
137-
res.json({
138-
token: captcha.token,
139-
image: captcha.data,
140-
});
141-
},
142-
}).attach(api);
132+
api.use(eggspress('/generate', {
133+
allowedMethods: ['GET'],
134+
}, async (req, res) => {
135+
const captcha = this.generateCaptcha();
136+
res.json({
137+
token: captcha.token,
138+
image: captcha.data,
139+
});
140+
}));
143141

144142
// Verify captcha endpoint
145-
Endpoint({
146-
route: '/verify',
147-
methods: ['POST'],
148-
handler: (req, res) => {
149-
const { token, answer } = req.body;
150-
151-
if ( !token || !answer ) {
152-
return res.status(400).json({
153-
valid: false,
154-
error: 'Missing token or answer',
155-
});
156-
}
143+
api.use(eggspress('/verify', {
144+
allowedMethods: ['POST'],
145+
}, (req, res) => {
146+
const { token, answer } = req.body;
147+
148+
if ( !token || !answer ) {
149+
return res.status(400).json({
150+
valid: false,
151+
error: 'Missing token or answer',
152+
});
153+
}
157154

158-
const isValid = this.verifyCaptcha(token, answer);
159-
res.json({ valid: isValid });
160-
},
161-
}).attach(api);
155+
const isValid = this.verifyCaptcha(token, answer);
156+
res.json({ valid: isValid });
157+
}));
162158

163159
// Special endpoint for automated testing
164160
// This should be disabled in production
@@ -430,8 +426,10 @@ class CaptchaService extends BaseService {
430426
// Invalid token or expired
431427
if ( ! captchaData ) {
432428
console.log('Verification FAILED: No data found for this token');
433-
console.log('TOKENS_TRACKING: Available tokens (first 8 chars):',
434-
Array.from(this.captchaTokens.keys()).map(t => t.substring(0, 8)));
429+
console.log(
430+
'TOKENS_TRACKING: Available tokens (first 8 chars):',
431+
Array.from(this.captchaTokens.keys()).map(t => t.substring(0, 8)),
432+
);
435433
this.log.debug(`Invalid captcha token: ${token}`);
436434
return false;
437435
}
@@ -542,29 +540,29 @@ class CaptchaService extends BaseService {
542540
};
543541

544542
switch ( this.difficulty ) {
545-
case 'easy':
546-
return {
547-
...baseOptions,
548-
size: 4,
549-
width: 150,
550-
height: 50,
551-
noise: 1,
552-
};
553-
case 'hard':
554-
return {
555-
...baseOptions,
556-
size: 7,
557-
width: 200,
558-
height: 60,
559-
noise: 3,
560-
};
561-
case 'medium':
562-
default:
563-
return {
564-
...baseOptions,
565-
width: 180,
566-
height: 50,
567-
};
543+
case 'easy':
544+
return {
545+
...baseOptions,
546+
size: 4,
547+
width: 150,
548+
height: 50,
549+
noise: 1,
550+
};
551+
case 'hard':
552+
return {
553+
...baseOptions,
554+
size: 7,
555+
width: 200,
556+
height: 60,
557+
noise: 3,
558+
};
559+
case 'medium':
560+
default:
561+
return {
562+
...baseOptions,
563+
width: 180,
564+
height: 50,
565+
};
568566
}
569567
}
570568

@@ -643,4 +641,4 @@ class CaptchaService extends BaseService {
643641

644642
// Export both as a named export and as a default export for compatibility
645643
module.exports = CaptchaService;
646-
module.exports.CaptchaService = CaptchaService;
644+
module.exports.CaptchaService = CaptchaService;

src/backend/src/modules/core/Core2Module.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ class Core2Module extends AdvancedBase {
5858
const { PagerService } = require('./PagerService.js');
5959
services.registerService('pager', PagerService);
6060

61-
const { ExpectationService } = require('./ExpectationService.js');
62-
services.registerService('expectations', ExpectationService);
63-
6461
const { ProcessEventService } = require('./ProcessEventService.js');
6562
services.registerService('process-event', ProcessEventService);
6663

0 commit comments

Comments
 (0)