fix: resolve 'app-'-prefixed app names in feedback target lookup

APP_NAME_REGEX allows names beginning with "app-" (e.g. the seeded
app-center), but resolveTargetApp's startsWith('app-') heuristic sent
those to a uid-only lookup with no name fallback, so feedback for such
apps 403'd even when enabled. Use AppStore.resolveApp (uid, then name)
like the rest of the codebase.
This commit is contained in:
Nariman Jelveh
2026-08-11 18:03:15 -07:00
parent 81402918d2
commit f4dfbd735b
2 changed files with 24 additions and 5 deletions
@@ -84,9 +84,10 @@ const makeUser = async (): Promise<{ actor: Actor; userId: number }> => {
const makeApp = async (
ownerUserId: number,
opts: { feedbackEnabled?: boolean; indexUrl?: string } = {},
opts: { feedbackEnabled?: boolean; indexUrl?: string; name?: string } = {},
) => {
const name = `fdbk-app-${Math.random().toString(36).slice(2, 10)}`;
const name =
opts.name ?? `fdbk-app-${Math.random().toString(36).slice(2, 10)}`;
return await server.stores.app.create(
{
name,
@@ -251,6 +252,24 @@ describe('AppFeedbackController GET /target', () => {
});
});
it('resolves an opted-in app whose name starts with "app-"', async () => {
const { userId: ownerId } = await makeUser();
const name = `app-fdbk-${Math.random().toString(36).slice(2, 10)}`;
const app = await makeApp(ownerId, { feedbackEnabled: true, name });
const { actor } = await makeUser();
const { res, captured } = makeRes();
await callRoute(
'get',
'/target',
makeReq({ query: { app: name }, actor }),
res,
);
expect(captured.body).toEqual({
enabled: true,
app: { name: app.name, title: app.title },
});
});
it('resolves an origin to the app whose index_url it matches', async () => {
const { userId: ownerId } = await makeUser();
const app = await makeApp(ownerId, { feedbackEnabled: true });
@@ -92,9 +92,9 @@ export class AppFeedbackService extends PuterService {
origin?: string;
}): Promise<Record<string, unknown> | null> {
if (app) {
return app.startsWith('app-')
? await this.stores.app.getByUid(app)
: await this.stores.app.getByName(app);
// Names may legally start with "app-" (e.g. "app-center"), so a
// prefix heuristic would misroute them; try uid first, then name.
return await this.stores.app.resolveApp(app);
}
if (origin) {
let uid;