Skip to content

Commit 69864b4

Browse files
gnekichemily-shen
andauthored
feat: ✨ introduce ip param for wrangler login command, fixes [5937] (#8316)
* feat: ✨ introduce ip param for wrangler login command fix issue 5937 by providing option to user to pass ip for the temporary login server, enabling the use of wrangler login command in devcontainers * style: 🎨 replace typo where console.log was used instead of logger.log * feat: ✨ introduce callback-host and callback-port param for wrangler login command * fix snapshot --------- Co-authored-by: emily-shen <[email protected]>
1 parent 5de2b9a commit 69864b4

File tree

4 files changed

+85
-4
lines changed

4 files changed

+85
-4
lines changed

.changeset/salty-ties-find.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
introduce callback-host and callback-port param for wrangler login command

packages/wrangler/src/__tests__/user.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,45 @@ describe("User", () => {
8080
});
8181
});
8282

83+
it("should login a user when `wrangler login` is run with custom callbackHost param", async () => {
84+
mockOAuthServerCallback("success");
85+
86+
let counter = 0;
87+
msw.use(
88+
http.post(
89+
"*/oauth2/token",
90+
async () => {
91+
counter += 1;
92+
93+
return HttpResponse.json({
94+
access_token: "test-access-token",
95+
expires_in: 100000,
96+
refresh_token: "test-refresh-token",
97+
scope: "account:read",
98+
});
99+
},
100+
{ once: true }
101+
)
102+
);
103+
104+
await runWrangler("login --callback-host='0.0.0.0'");
105+
106+
expect(counter).toBe(1);
107+
expect(std.out).toMatchInlineSnapshot(`
108+
"Attempting to login via OAuth...
109+
Temporary login server listening on 0.0.0.0:8976
110+
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth?response_type=code&client_id=54d11594-84e4-41aa-b438-e81b8fa78ee7&redirect_uri=http%3A%2F%2Flocalhost%3A8976%2Foauth%2Fcallback&scope=account%3Aread%20user%3Aread%20workers%3Awrite%20workers_kv%3Awrite%20workers_routes%3Awrite%20workers_scripts%3Awrite%20workers_tail%3Aread%20d1%3Awrite%20pages%3Awrite%20zone%3Aread%20ssl_certs%3Awrite%20ai%3Awrite%20queues%3Awrite%20pipelines%3Awrite%20secrets_store%3Awrite%20offline_access&state=MOCK_STATE_PARAM&code_challenge=MOCK_CODE_CHALLENGE&code_challenge_method=S256
111+
Successfully logged in."
112+
`);
113+
expect(readAuthConfigFile()).toEqual<UserAuthConfig>({
114+
api_token: undefined,
115+
oauth_token: "test-access-token",
116+
refresh_token: "test-refresh-token",
117+
expiration_time: expect.any(String),
118+
scopes: ["account:read"],
119+
});
120+
});
121+
83122
it("login works in a different environment", async () => {
84123
vi.stubEnv("WRANGLER_API_ENVIRONMENT", "staging");
85124
mockOAuthServerCallback("success");

packages/wrangler/src/user/commands.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ export const loginCommand = createCommand({
2828
type: "string",
2929
requiresArg: true,
3030
},
31+
"callback-host": {
32+
describe:
33+
"Use the ip or host address for the temporary login callback server.",
34+
type: "string",
35+
requiresArg: false,
36+
default: "localhost",
37+
},
38+
"callback-port": {
39+
describe: "Use the port for the temporary login callback server.",
40+
type: "number",
41+
requiresArg: false,
42+
default: 8976,
43+
},
3144
},
3245
async handler(args, { config }) {
3346
if (args.scopesList) {
@@ -45,10 +58,19 @@ export const loginCommand = createCommand({
4558
`One of ${args.scopes} is not a valid authentication scope. Run "wrangler login --scopes-list" to see the valid scopes.`
4659
);
4760
}
48-
await login({ scopes: args.scopes, browser: args.browser });
61+
await login({
62+
scopes: args.scopes,
63+
browser: args.browser,
64+
callbackHost: args.callbackHost,
65+
callbackPort: args.callbackPort,
66+
});
4967
return;
5068
}
51-
await login({ browser: args.browser });
69+
await login({
70+
browser: args.browser,
71+
callbackHost: args.callbackHost,
72+
callbackPort: args.callbackPort,
73+
});
5274
metrics.sendMetricsEvent("login user", {
5375
sendMetrics: config.send_metrics,
5476
});

packages/wrangler/src/user/user.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@ export function readAuthConfigFile(): UserAuthConfig {
914914
type LoginProps = {
915915
scopes?: Scope[];
916916
browser: boolean;
917+
callbackHost: string;
918+
callbackPort: number;
917919
};
918920

919921
export async function loginOrRefreshIfRequired(
@@ -952,6 +954,8 @@ export async function getOauthToken(options: {
952954
granted: {
953955
url: string;
954956
};
957+
callbackHost: string;
958+
callbackPort: number;
955959
}): Promise<AccessContext> {
956960
const urlToOpen = await getAuthURL(options.scopes, options.clientId);
957961
let server: http.Server;
@@ -1028,7 +1032,12 @@ export async function getOauthToken(options: {
10281032
}
10291033
});
10301034

1031-
server.listen(8976, "localhost");
1035+
if (options.callbackHost !== "localhost" || options.callbackPort !== 8976) {
1036+
logger.log(
1037+
`Temporary login server listening on ${options.callbackHost}:${options.callbackPort}`
1038+
);
1039+
}
1040+
server.listen(options.callbackPort, options.callbackHost);
10321041
});
10331042
if (options.browser) {
10341043
logger.log(`Opening a link in your default browser: ${urlToOpen}`);
@@ -1041,7 +1050,11 @@ export async function getOauthToken(options: {
10411050
}
10421051

10431052
export async function login(
1044-
props: LoginProps = { browser: true }
1053+
props: LoginProps = {
1054+
browser: true,
1055+
callbackHost: "localhost",
1056+
callbackPort: 8976,
1057+
}
10451058
): Promise<boolean> {
10461059
const authFromEnv = getAuthFromEnv();
10471060
if (authFromEnv) {
@@ -1068,6 +1081,8 @@ export async function login(
10681081
granted: {
10691082
url: "https://welcome.developers.workers.dev/wrangler-oauth-consent-granted",
10701083
},
1084+
callbackHost: props.callbackHost,
1085+
callbackPort: props.callbackPort,
10711086
});
10721087

10731088
writeAuthConfigFile({

0 commit comments

Comments
 (0)