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
21 changes: 15 additions & 6 deletions src/commands/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,27 @@ import { useMaskedInput } from '../../lib/hooks/user-confirmations/useMaskedInpu
import { useSelectFromList } from '../../lib/hooks/user-confirmations/useSelectFromList.js';
import { createLocalApiServer } from '../../lib/local-api-server.js';
import { error, info, success, warning } from '../../lib/outputs.js';
import { runtimeApiUrl } from '../../lib/runtime/docker.js';
import { configuredRuntimePorts, resolveApiBaseUrl } from '../../lib/runtime/target.js';
import { tildify } from '../../lib/utils.js';

// When logging in against a local Console instance (local platform development), validate the token
// against the local API rather than production.
const LOCAL_API_BASE_URL = 'http://localhost:3333';

// Not really checked right now, but it might come useful if we ever need to do some breaking changes
const API_VERSION = 'v1';

/**
* Where the token is validated. `APIFY_CLIENT_BASE_URL` and a connected Actor runtime win. Otherwise a local
* Console (a hand-started runtime, or local platform development) means the local API: the port the
* runtime was last started on, or 3333 when none is known.
*/
export function resolveLoginApiBaseUrl(): string | undefined {
const explicit = resolveApiBaseUrl();
if (explicit) return explicit;

return getConsoleUrl().includes('localhost') ? runtimeApiUrl(configuredRuntimePorts().api) : undefined;
}

const tryToLogin = async (token: string) => {
const apiBaseUrl = getConsoleUrl().includes('localhost') ? LOCAL_API_BASE_URL : undefined;
const result = await loginWithToken(token, apiBaseUrl);
const result = await loginWithToken(token, resolveLoginApiBaseUrl());

if (result) {
const { userInfo } = result;
Expand Down
45 changes: 45 additions & 0 deletions test/local/commands/login-api-base-url.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { resolveLoginApiBaseUrl } from '../../../src/commands/auth/login.js';
import { updateActorRuntimeConfig } from '../../../src/lib/runtime/config.js';
import { setConnectedToActorRuntime } from '../../../src/lib/runtime/target.js';
import { useAuthSetup } from '../../__setup__/hooks/useAuthSetup.js';

useAuthSetup();

describe('apify login API base URL', () => {
beforeEach(() => {
vitest.stubEnv('APIFY_CLIENT_BASE_URL', '');
vitest.stubEnv('APIFY_CONSOLE_URL', '');
});

it('validates against the Apify platform by default', () => {
expect(resolveLoginApiBaseUrl()).toBeUndefined();
});

it('falls back to port 3333 for a local Console when no runtime port is known', () => {
vitest.stubEnv('APIFY_CONSOLE_URL', 'http://localhost:3000');

expect(resolveLoginApiBaseUrl()).toBe('http://localhost:3333');
});

it('uses the port the runtime was last started on for a local Console', () => {
vitest.stubEnv('APIFY_CONSOLE_URL', 'http://localhost:4000');
updateActorRuntimeConfig({ apiPort: 4333, consolePort: 4000 });

expect(resolveLoginApiBaseUrl()).toBe('http://localhost:4333');
});

it('targets the connected runtime on its configured port', () => {
updateActorRuntimeConfig({ apiPort: 4333, consolePort: 4000 });
setConnectedToActorRuntime(true);

expect(resolveLoginApiBaseUrl()).toBe('http://localhost:4333');
});

it('lets APIFY_CLIENT_BASE_URL win over a local Console and a connected runtime', () => {
vitest.stubEnv('APIFY_CLIENT_BASE_URL', 'https://api.example.com');
vitest.stubEnv('APIFY_CONSOLE_URL', 'http://localhost:3000');
setConnectedToActorRuntime(true);

expect(resolveLoginApiBaseUrl()).toBe('https://api.example.com');
});
});
Loading