mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(cli): rename proxy cli to tunnel (#6442)
This commit is contained in:
parent
ff6b304bac
commit
976558af9c
5 changed files with 59 additions and 22 deletions
33
.changeset/long-rabbits-roll.md
Normal file
33
.changeset/long-rabbits-roll.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
"@logto/cli": minor
|
||||
---
|
||||
|
||||
add new cli command to setup Logto tunnel service for developing and debugging custom ui on your local machine
|
||||
|
||||
This command will establish a tunnel service between the following 3 entities: Logto cloud auth services, your application, and your custom sign-in UI.
|
||||
|
||||
Assuming you have a custom sign-in page running on `http://localhost:4000`, then you can execute the command this way:
|
||||
|
||||
```bash
|
||||
logto tunnel --endpoint https://<tenant-id>.logto.app --port 9000 --experience-uri http://localhost:4000
|
||||
```
|
||||
|
||||
Or if you don't have your custom UI pages hosted on a dev server, you can use the `--experience-path` option to specify the path to your static files:
|
||||
|
||||
```bash
|
||||
logto tunnel --endpoint https://<tenant-id>.logto.app --port 9000 --experience-path /path/to/your/custom/ui
|
||||
```
|
||||
|
||||
This command also works if you have enabled custom domain in your Logto tenant. E.g.:
|
||||
|
||||
```bash
|
||||
logto tunnel --endpoint https://your-custom-domain.com --port 9000 --experience-path /path/to/your/custom/ui
|
||||
```
|
||||
|
||||
This should set up the tunnel and it will be running on your local machine at `http://localhost:9000/`.
|
||||
|
||||
Finally, run your application and set its endpoint in Logto config to the tunnel address `http://localhost:9000/` instead.
|
||||
|
||||
If all set up correctly, when you click the "sign-in" button in your application, you should be navigated to your custom sign-in page instead of Logto's built-in UI, along with valid session (cookies) that allows you to further interact with Logto experience API.
|
||||
|
||||
Refer to the [documentation](https://docs.logto.dev/docs/references/using-cli/tunnel/) for more details.
|
|
@ -7,7 +7,7 @@ import type { CommandModule } from 'yargs';
|
|||
|
||||
import { consoleLog } from '../../utils.js';
|
||||
|
||||
import { type ProxyCommandArgs } from './types.js';
|
||||
import { type TunnelCommandArgs } from './types.js';
|
||||
import {
|
||||
checkExperienceInput,
|
||||
createLogtoResponseHandler,
|
||||
|
@ -16,9 +16,9 @@ import {
|
|||
isLogtoRequestPath,
|
||||
} from './utils.js';
|
||||
|
||||
const proxy: CommandModule<unknown, ProxyCommandArgs> = {
|
||||
command: ['proxy'],
|
||||
describe: 'Command for Logto proxy',
|
||||
const tunnel: CommandModule<unknown, TunnelCommandArgs> = {
|
||||
command: ['tunnel'],
|
||||
describe: 'Command for Logto tunnel',
|
||||
builder: (yargs) =>
|
||||
yargs
|
||||
.options({
|
||||
|
@ -40,7 +40,8 @@ const proxy: CommandModule<unknown, ProxyCommandArgs> = {
|
|||
},
|
||||
port: {
|
||||
alias: 'p',
|
||||
describe: 'The port number where the proxy server will be running on. Defaults to 9000.',
|
||||
describe:
|
||||
'The port number where the tunnel service will be running on. Defaults to 9000.',
|
||||
type: 'number',
|
||||
default: 9000,
|
||||
},
|
||||
|
@ -59,7 +60,7 @@ const proxy: CommandModule<unknown, ProxyCommandArgs> = {
|
|||
consoleLog.fatal('A valid Logto endpoint URI must be provided.');
|
||||
}
|
||||
const logtoEndpointUrl = new URL(endpoint);
|
||||
const proxyUrl = new URL(`http://localhost:${port}`);
|
||||
const tunnelServiceUrl = new URL(`http://localhost:${port}`);
|
||||
|
||||
const proxyLogtoRequest = createProxy(
|
||||
logtoEndpointUrl.href,
|
||||
|
@ -69,7 +70,7 @@ const proxy: CommandModule<unknown, ProxyCommandArgs> = {
|
|||
request,
|
||||
response,
|
||||
logtoEndpointUrl,
|
||||
proxyUrl,
|
||||
tunnelServiceUrl,
|
||||
verbose,
|
||||
})
|
||||
);
|
||||
|
@ -81,7 +82,7 @@ const proxy: CommandModule<unknown, ProxyCommandArgs> = {
|
|||
consoleLog.info(`Incoming request: ${chalk.blue(request.method, request.url)}`);
|
||||
}
|
||||
|
||||
// Proxy the requests to Logto endpoint
|
||||
// Tunneling the requests to Logto endpoint
|
||||
if (isLogtoRequestPath(request.url)) {
|
||||
void proxyLogtoRequest(request, response);
|
||||
return;
|
||||
|
@ -98,9 +99,9 @@ const proxy: CommandModule<unknown, ProxyCommandArgs> = {
|
|||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
consoleLog.info(`Proxy server is running on ${chalk.blue(proxyUrl.href)}`);
|
||||
consoleLog.info(`Logto tunnel is running on ${chalk.blue(tunnelServiceUrl.href)}`);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default proxy;
|
||||
export default tunnel;
|
|
@ -1,6 +1,6 @@
|
|||
import type * as http from 'node:http';
|
||||
|
||||
export type ProxyCommandArgs = {
|
||||
export type TunnelCommandArgs = {
|
||||
'experience-uri'?: string;
|
||||
'experience-path'?: string;
|
||||
endpoint?: string;
|
||||
|
@ -8,11 +8,11 @@ export type ProxyCommandArgs = {
|
|||
verbose: boolean;
|
||||
};
|
||||
|
||||
export type ProxyResponseHandler = {
|
||||
export type LogtoResponseHandler = {
|
||||
proxyResponse: http.IncomingMessage;
|
||||
request: http.IncomingMessage;
|
||||
response: http.ServerResponse;
|
||||
logtoEndpointUrl: URL;
|
||||
proxyUrl: URL;
|
||||
tunnelServiceUrl: URL;
|
||||
verbose: boolean;
|
||||
};
|
|
@ -12,7 +12,7 @@ import mime from 'mime';
|
|||
|
||||
import { consoleLog } from '../../utils.js';
|
||||
|
||||
import { type ProxyResponseHandler } from './types.js';
|
||||
import { type LogtoResponseHandler } from './types.js';
|
||||
|
||||
export const createProxy = (targetUrl: string, onProxyResponse?: OnProxyEvent['proxyRes']) => {
|
||||
const hasResponseHandler = Boolean(onProxyResponse);
|
||||
|
@ -65,7 +65,7 @@ export const createStaticFileProxy =
|
|||
|
||||
/**
|
||||
* Intercept the response from Logto endpoint and replace Logto endpoint URLs in the response with the
|
||||
* proxy URL. The string replace happens in the following cases:
|
||||
* tunnel service URL. The string replace happens in the following cases:
|
||||
* - The response is a redirect response, and the `location` property in response header may contain Logto
|
||||
* endpoint URI.
|
||||
* - The response body is JSON, which consists of properties such as `**_endpoint` and `redirectTo`. These
|
||||
|
@ -80,13 +80,13 @@ export const createLogtoResponseHandler = async ({
|
|||
request,
|
||||
response,
|
||||
logtoEndpointUrl,
|
||||
proxyUrl,
|
||||
tunnelServiceUrl,
|
||||
verbose,
|
||||
}: ProxyResponseHandler) => {
|
||||
}: LogtoResponseHandler) => {
|
||||
const { location } = proxyResponse.headers;
|
||||
if (location) {
|
||||
// eslint-disable-next-line @silverhand/fp/no-mutation
|
||||
proxyResponse.headers.location = location.replace(logtoEndpointUrl.href, proxyUrl.href);
|
||||
proxyResponse.headers.location = location.replace(logtoEndpointUrl.href, tunnelServiceUrl.href);
|
||||
}
|
||||
|
||||
void responseInterceptor(async (responseBuffer, proxyResponse) => {
|
||||
|
@ -96,7 +96,10 @@ export const createLogtoResponseHandler = async ({
|
|||
}
|
||||
|
||||
if (proxyResponse.headers['content-type']?.includes('text/html')) {
|
||||
return responseBody.replace(`action="${logtoEndpointUrl.href}`, `action="${proxyUrl.href}`);
|
||||
return responseBody.replace(
|
||||
`action="${logtoEndpointUrl.href}`,
|
||||
`action="${tunnelServiceUrl.href}`
|
||||
);
|
||||
}
|
||||
|
||||
if (proxyResponse.headers['content-type']?.includes('application/json')) {
|
||||
|
@ -106,7 +109,7 @@ export const createLogtoResponseHandler = async ({
|
|||
const updatedEntries: Array<[string, unknown]> = Object.entries(jsonData).map(
|
||||
([key, value]) => {
|
||||
if ((key === 'redirectTo' || key.endsWith('_endpoint')) && typeof value === 'string') {
|
||||
return [key, value.replace(logtoEndpointUrl.href, proxyUrl.href)];
|
||||
return [key, value.replace(logtoEndpointUrl.href, tunnelServiceUrl.href)];
|
||||
}
|
||||
return [key, value];
|
||||
}
|
|
@ -6,8 +6,8 @@ import { hideBin } from 'yargs/helpers';
|
|||
import connector from './commands/connector/index.js';
|
||||
import database from './commands/database/index.js';
|
||||
import install from './commands/install/index.js';
|
||||
import proxy from './commands/proxy/index.js';
|
||||
import translate from './commands/translate/index.js';
|
||||
import tunnel from './commands/tunnel/index.js';
|
||||
import { packageJson } from './package-json.js';
|
||||
import { cliConfig, ConfigKey, consoleLog } from './utils.js';
|
||||
|
||||
|
@ -49,7 +49,7 @@ void yargs(hideBin(process.argv))
|
|||
.command(database)
|
||||
.command(connector)
|
||||
.command(translate)
|
||||
.command(proxy)
|
||||
.command(tunnel)
|
||||
.demandCommand(1)
|
||||
.showHelpOnFail(false, `Specify ${chalk.green('--help')} for available options`)
|
||||
.strict()
|
||||
|
|
Loading…
Reference in a new issue