mirror of
https://github.com/tsl0922/ttyd.git
synced 2025-12-22 03:44:19 +01:00
html: use api to fetch auth token
This commit is contained in:
@@ -65,6 +65,7 @@
|
|||||||
"decko": "^1.2.0",
|
"decko": "^1.2.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"preact": "^10.0.5",
|
"preact": "^10.0.5",
|
||||||
|
"whatwg-fetch": "^3.0.0",
|
||||||
"xterm": "^4.4.0",
|
"xterm": "^4.4.0",
|
||||||
"xterm-addon-fit": "^0.3.0",
|
"xterm-addon-fit": "^0.3.0",
|
||||||
"xterm-addon-web-links": "^0.2.1",
|
"xterm-addon-web-links": "^0.2.1",
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ if ((module as any).hot) {
|
|||||||
require('preact/debug');
|
require('preact/debug');
|
||||||
}
|
}
|
||||||
|
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
const wsPath = window.location.pathname.endsWith('/') ? 'ws' : '/ws';
|
const path = window.location.pathname.replace(/[\/]+$/, '');
|
||||||
const url = [protocol, window.location.host, window.location.pathname, wsPath, window.location.search].join('');
|
const wsUrl = [protocol, '//', window.location.host, path, '/ws', window.location.search].join('');
|
||||||
|
const tokenUrl = [window.location.protocol, '//', window.location.host, path, '/token'].join('');
|
||||||
const termOptions = {
|
const termOptions = {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: 'Menlo For Powerline,Consolas,Liberation Mono,Menlo,Courier,monospace',
|
fontFamily: 'Menlo For Powerline,Consolas,Liberation Mono,Menlo,Courier,monospace',
|
||||||
@@ -39,6 +40,6 @@ const termOptions = {
|
|||||||
|
|
||||||
export class App extends Component {
|
export class App extends Component {
|
||||||
render() {
|
render() {
|
||||||
return <Xterm id="terminal-container" url={url} options={termOptions} />;
|
return <Xterm id="terminal-container" wsUrl={wsUrl} tokenUrl={tokenUrl} options={termOptions} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ export interface TerminalExtended extends Terminal {
|
|||||||
|
|
||||||
export interface WindowExtended extends Window {
|
export interface WindowExtended extends Window {
|
||||||
term: TerminalExtended;
|
term: TerminalExtended;
|
||||||
tty_auth_token?: string;
|
|
||||||
}
|
}
|
||||||
declare let window: WindowExtended;
|
declare let window: WindowExtended;
|
||||||
|
|
||||||
@@ -34,7 +33,8 @@ const enum Command {
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
url: string;
|
wsUrl: string;
|
||||||
|
tokenUrl: string;
|
||||||
options: ITerminalOptions;
|
options: ITerminalOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ export class Xterm extends Component<Props> {
|
|||||||
private overlayAddon: OverlayAddon;
|
private overlayAddon: OverlayAddon;
|
||||||
private zmodemAddon: ZmodemAddon;
|
private zmodemAddon: ZmodemAddon;
|
||||||
private socket: WebSocket;
|
private socket: WebSocket;
|
||||||
|
private token: string;
|
||||||
private title: string;
|
private title: string;
|
||||||
private resizeTimeout: number;
|
private resizeTimeout: number;
|
||||||
private backoff: backoff.Backoff;
|
private backoff: backoff.Backoff;
|
||||||
@@ -65,7 +66,7 @@ export class Xterm extends Component<Props> {
|
|||||||
});
|
});
|
||||||
this.backoff.on('ready', () => {
|
this.backoff.on('ready', () => {
|
||||||
this.backoffLock = false;
|
this.backoffLock = false;
|
||||||
this.openTerminal();
|
this.refreshToken().then(this.openTerminal);
|
||||||
});
|
});
|
||||||
this.backoff.on('backoff', (_, delay: number) => {
|
this.backoff.on('backoff', (_, delay: number) => {
|
||||||
console.log(`[ttyd] will attempt to reconnect websocket in ${delay}ms`);
|
console.log(`[ttyd] will attempt to reconnect websocket in ${delay}ms`);
|
||||||
@@ -73,7 +74,8 @@ export class Xterm extends Component<Props> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
async componentDidMount() {
|
||||||
|
await this.refreshToken();
|
||||||
this.openTerminal();
|
this.openTerminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +104,19 @@ export class Xterm extends Component<Props> {
|
|||||||
socket.send(payload);
|
socket.send(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bind
|
||||||
|
private async refreshToken() {
|
||||||
|
try {
|
||||||
|
const resp = await fetch(this.props.tokenUrl);
|
||||||
|
if (resp.ok) {
|
||||||
|
const json = await resp.json();
|
||||||
|
this.token = json.token;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`[ttyd] fetch ${this.props.tokenUrl}: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
private onWindowResize() {
|
private onWindowResize() {
|
||||||
const { fitAddon } = this;
|
const { fitAddon } = this;
|
||||||
@@ -121,7 +136,7 @@ export class Xterm extends Component<Props> {
|
|||||||
this.terminal.dispose();
|
this.terminal.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.socket = new WebSocket(this.props.url, ['tty']);
|
this.socket = new WebSocket(this.props.wsUrl, ['tty']);
|
||||||
this.terminal = new Terminal(this.props.options);
|
this.terminal = new Terminal(this.props.options);
|
||||||
const { socket, terminal, container, fitAddon, overlayAddon } = this;
|
const { socket, terminal, container, fitAddon, overlayAddon } = this;
|
||||||
window.term = terminal as TerminalExtended;
|
window.term = terminal as TerminalExtended;
|
||||||
@@ -174,9 +189,7 @@ export class Xterm extends Component<Props> {
|
|||||||
this.backoff.reset();
|
this.backoff.reset();
|
||||||
|
|
||||||
const { socket, textEncoder, fitAddon } = this;
|
const { socket, textEncoder, fitAddon } = this;
|
||||||
const authToken = window.tty_auth_token;
|
socket.send(textEncoder.encode(JSON.stringify({ AuthToken: this.token })));
|
||||||
|
|
||||||
socket.send(textEncoder.encode(JSON.stringify({ AuthToken: authToken })));
|
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,11 +201,6 @@ export class Xterm extends Component<Props> {
|
|||||||
overlayAddon.showOverlay('Connection Closed', null);
|
overlayAddon.showOverlay('Connection Closed', null);
|
||||||
window.removeEventListener('beforeunload', this.onWindowUnload);
|
window.removeEventListener('beforeunload', this.onWindowUnload);
|
||||||
|
|
||||||
// 1008: POLICY_VIOLATION - Auth failure
|
|
||||||
if (event.code === 1008) {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1000: CLOSE_NORMAL
|
// 1000: CLOSE_NORMAL
|
||||||
if (event.code !== 1000) {
|
if (event.code !== 1000) {
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'whatwg-fetch';
|
||||||
import { h, render } from 'preact';
|
import { h, render } from 'preact';
|
||||||
import { App } from './components/app';
|
import { App } from './components/app';
|
||||||
import './style/index.scss';
|
import './style/index.scss';
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="auth_token.js"></script>
|
|
||||||
<% for (const js in htmlWebpackPlugin.files.js) { %>
|
<% for (const js in htmlWebpackPlugin.files.js) { %>
|
||||||
<script inline type="text/javascript" src="<%= htmlWebpackPlugin.files.js[js] %>"></script>
|
<script inline type="text/javascript" src="<%= htmlWebpackPlugin.files.js[js] %>"></script>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ const devConfig = {
|
|||||||
compress: true,
|
compress: true,
|
||||||
port: 9000,
|
port: 9000,
|
||||||
proxy: [{
|
proxy: [{
|
||||||
context: ['/auth_token.js', '/ws'],
|
context: ['/token', '/ws'],
|
||||||
target: 'http://localhost:7681',
|
target: 'http://localhost:7681',
|
||||||
ws: true
|
ws: true
|
||||||
}]
|
}]
|
||||||
|
|||||||
@@ -8477,6 +8477,11 @@ websocket-extensions@>=0.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
||||||
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
||||||
|
|
||||||
|
whatwg-fetch@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
|
||||||
|
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
|
||||||
|
|
||||||
which-module@^1.0.0:
|
which-module@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
|
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
|
||||||
|
|||||||
16853
src/html.h
16853
src/html.h
File diff suppressed because it is too large
Load Diff
@@ -149,15 +149,15 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, voi
|
|||||||
p = buffer + LWS_PRE;
|
p = buffer + LWS_PRE;
|
||||||
end = p + sizeof(buffer) - LWS_PRE;
|
end = p + sizeof(buffer) - LWS_PRE;
|
||||||
|
|
||||||
if (strncmp(pss->path, "/auth_token.js", 14) == 0) {
|
if (strncmp(pss->path, "/token", 6) == 0) {
|
||||||
const char *credential = server->credential != NULL ? server->credential : "";
|
const char *credential = server->credential != NULL ? server->credential : "";
|
||||||
size_t n = sprintf(buf, "var tty_auth_token = '%s';\n", credential);
|
size_t n = sprintf(buf, "{\"token\": \"%s\"}", credential);
|
||||||
if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
|
if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
|
||||||
return 1;
|
return 1;
|
||||||
if (lws_add_http_header_by_token(wsi,
|
if (lws_add_http_header_by_token(wsi,
|
||||||
WSI_TOKEN_HTTP_CONTENT_TYPE,
|
WSI_TOKEN_HTTP_CONTENT_TYPE,
|
||||||
(unsigned char *) "application/javascript",
|
(unsigned char *) "application/json;charset=utf-8",
|
||||||
22, &p, end))
|
30, &p, end))
|
||||||
return 1;
|
return 1;
|
||||||
if (lws_add_http_header_content_length(wsi, (unsigned long) n, &p, end))
|
if (lws_add_http_header_content_length(wsi, (unsigned long) n, &p, end))
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user