Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/__tests__/controllers/UserController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,24 @@ describe('UserController.secondOnboarding', () => {
expect(res.json).toHaveBeenCalledWith({});
expect(userService.getSecondOnboardings).not.toHaveBeenCalled();
});

it('does not 500 when app_version is missing from the request (regression: semver gte on undefined)', async () => {
// gte(undefined, minVersion) used to throw "Invalid version" before any
// onboarding logic ran. first_seen = now keeps us in the <7-day early return.
const res = makeRes();
await expect(
controller.secondOnboarding(
{
body: {
rc_id: 'rc_123',
region: 'USA',
first_seen: Math.floor(Date.now() / 1000),
},
} as any,
res,
),
).resolves.toBeDefined();

expect(res.json).toHaveBeenCalledWith({});
});
});
14 changes: 11 additions & 3 deletions src/controllers/UserController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import cookie from 'cookie';
import { UserEventEnum } from '../types/user';
import moment from 'moment-timezone';
import { SubscriptionService } from '../services/SubscriptionService';
import { gte } from 'semver';
import { gte, valid } from 'semver';

export class UserController {
constructor(
Expand All @@ -14,6 +14,14 @@ export class UserController {

private readonly minVersion = '5.6.0';

/// semver's gte throws when app_version is missing/malformed (e.g. an older
/// client that omits it from the body), which surfaced as an unlogged 500 on
/// /user/second_onboarding. Treat any non-semver value as "not supported".
private meetsMinVersion(version?: string): boolean {
const parsed = valid(version);
return parsed != null && gte(parsed, this.minVersion);
}

public async getAuth(req: IRequest, res: IResponse): Promise<IResponse> {
const user = req.user;
res.json({ user, message: !user ? 'login' : 'dashboard' });
Expand Down Expand Up @@ -206,7 +214,7 @@ export class UserController {
return res.json({});
}

const isVersionSupported = gte(app_version, this.minVersion);
const isVersionSupported = this.meetsMinVersion(app_version);

/// Only allow AUS, ESP, PHL, MEX, RUS region for tip only onboarding
if (
Expand Down Expand Up @@ -307,7 +315,7 @@ export class UserController {
external_id: rc_id,
});

const isVersionSupported = gte(app_version, this.minVersion);
const isVersionSupported = this.meetsMinVersion(app_version);
switch (region) {
case 'USA':
if (totalCount <= 1) {
Expand Down
Loading