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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Use base image to build the project avoid npm install every time
FROM jumpserver/luna-base:20250609_105214 AS stage-build
FROM jumpserver/luna-base:20260320_114803 AS stage-build

ARG VERSION
ENV VERSION=$VERSION
Expand Down
4 changes: 3 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"aot": false,
"sourceMap": true,
"namedChunks": true,
"baseHref": "/luna/",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": ["src/polyfills.ts"],
Expand Down Expand Up @@ -101,7 +102,8 @@
"builder": "@angular/build:dev-server",
"options": {
"buildTarget": "Luna:build",
"proxyConfig": "proxy.conf.json"
"proxyConfig": "proxy.conf.json",
"servePath": "/luna"
},
"configurations": {
"production": {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"license": "GPLv3",
"scripts": {
"ng": "ng",
"dev": "ng serve --proxy-config proxy.conf.json --hmr --host 0.0.0.0",
"start": "ng serve --proxy-config proxy.conf.json --host 0.0.0.0",
"dev": "ng serve --proxy-config proxy.conf.json --serve-path /luna --hmr --host 0.0.0.0",
"start": "ng serve --proxy-config proxy.conf.json --serve-path /luna --host 0.0.0.0",
"build": "ng build --configuration production",
"test": "ng test",
"lint": "ng lint",
Expand Down
13 changes: 5 additions & 8 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,19 @@ import { AppComponent } from './pages/app.component';
import { ElementComponents } from './elements/elements.component';
import { PluginModules } from './plugins/plugins';
import { ClipboardService } from 'ngx-clipboard';
import { environment, version } from '../environments/environment';
import { version } from '../environments/environment';
import { BehaviorSubject, forkJoin, Observable, of } from 'rxjs';
import { FileInputAccessorModule } from 'file-input-accessor';
import { catchError, mergeMap } from 'rxjs/operators';
import { PagesComponents } from './pages/pages.component';
import { getAppBasePath, withAppBase, withSitePrefix } from '@app/utils/path';

export class CustomLoader implements TranslateLoader {
constructor(private http: HttpClient) {}

public getTranslation(lang: String): Observable<any> {
const remote = '/api/v1/settings/i18n/luna/?lang=' + lang + '&v=' + version;
let local = '/assets/i18n/' + lang + '.json';
const isProd = environment.production;
if (isProd) {
local = '/luna' + local;
}
const remote = withSitePrefix('/api/v1/settings/i18n/luna/?lang=' + lang + '&v=' + version);
const local = withAppBase('/assets/i18n/' + lang + '.json');

return forkJoin([
this.http.get(remote).pipe(catchError(() => of({}))),
Expand Down Expand Up @@ -74,7 +71,7 @@ export class CustomLoader implements TranslateLoader {
bootstrap: [AppComponent],
providers: [
...AllServices,
{ provide: APP_BASE_HREF, useValue: '/luna/' },
{ provide: APP_BASE_HREF, useFactory: getAppBasePath },
CookieService,
NGXLogger,
ClipboardService,
Expand Down
3 changes: 2 additions & 1 deletion src/app/elements/chat/chat.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
HostListener,
AfterViewInit
} from '@angular/core';
import { withUIBase } from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -157,7 +158,7 @@ export class ElementChatComponent implements OnInit, OnDestroy, AfterViewInit {
}

private listenChatAI(): void {
this.iframeURL = '/ui/#/chat/chat-ai?from=luna';
this.iframeURL = withUIBase('#/chat/chat-ai?from=luna');

window.addEventListener('message', event => {
// 确认消息的来源是你信任的域
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, Inject, OnInit} from '@angular/core';
import {NZ_MODAL_DATA} from "ng-zorro-antd/modal";
import {withSitePrefix} from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -32,6 +33,6 @@ export class ElementDownloadDialogComponent implements OnInit {
if (this.ignoreRemind) {
localStorage.setItem('hasDownLoadApp', '1');
}
window.open('/core/download/', '_blank');
window.open(withSitePrefix('/core/download/'), '_blank');
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import {Asset, Endpoint, View} from '@app/model';
import {joinEndpointUrl} from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -40,16 +41,16 @@ export class ElementConnectorDefaultComponent implements OnInit {
const token = this.view.connectToken.id;
switch (this.connector) {
case 'chen':
const url = `${endpointUrl}/chen/connect?token=${token}`;
const url = joinEndpointUrl(endpointUrl, `/chen/connect?token=${token}`);
const disableautohash = this.view.getConnectOption('disableautohash');
if (disableautohash) {
return `${url}&disableautohash=true`;
}
return url;
case 'lion':
return `${endpointUrl}/lion/connect?token=${token}`;
return joinEndpointUrl(endpointUrl, `/lion/connect?token=${token}`);
case 'default':
return `${endpointUrl}/koko/connect?token=${token}`;
return joinEndpointUrl(endpointUrl, `/koko/connect?token=${token}`);
}
}
}
12 changes: 8 additions & 4 deletions src/app/elements/content/content-window/koko/koko.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@app/services';
import { User } from '@app/globals';
import { Command, InfoItem } from '../guide/model';
import { joinEndpointUrl } from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -54,7 +55,7 @@ export class ElementConnectorKokoComponent implements OnInit {
this.account = account;
this.token = connectToken;
const url = smartEndpoint.getUrl();
this.baseUrl = `${url}/koko`;
this.baseUrl = url;
this.methodName = this.view.connectMethod.value;
if (this.methodName === 'ssh_guide') {
this.setInfoItems();
Expand Down Expand Up @@ -165,14 +166,17 @@ export class ElementConnectorKokoComponent implements OnInit {
});

if (this.protocol === 'k8s') {
return (this.iframeURL = `${this.baseUrl}/k8s/?` + query);
return (this.iframeURL = joinEndpointUrl(this.baseUrl, `/koko/k8s/?${query}`));
}

this.iframeURL = `${this.baseUrl}/connect/?` + query;
this.iframeURL = joinEndpointUrl(this.baseUrl, `/koko/connect/?${query}`);
}

generateFileManagerURL() {
this.iframeURL = `${this.baseUrl}/elfinder/sftp/?token=${this.view.connectToken.id}&asset=${this.asset.id}`;
this.iframeURL = joinEndpointUrl(
this.baseUrl,
`/koko/elfinder/sftp/?token=${this.view.connectToken.id}&asset=${this.asset.id}`
);
}

async reconnect() {
Expand Down
7 changes: 4 additions & 3 deletions src/app/elements/nav/nav.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
SettingService,
ViewService
} from '@app/services';
import { withSitePrefix, withUIBase } from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -59,7 +60,7 @@ export class ElementNavComponent implements OnInit {
{
id: 'Connect',
click: () => {
window.open('/koko/elfinder/sftp/');
window.open(withSitePrefix('/koko/elfinder/sftp/'));
},
name: 'Connect'
}
Expand Down Expand Up @@ -171,7 +172,7 @@ export class ElementNavComponent implements OnInit {
{
id: 'Download',
click: () => {
window.open('/core/download/', '_blank');
window.open(withSitePrefix('/core/download/'), '_blank');
},
name: 'Download'
}
Expand Down Expand Up @@ -217,6 +218,6 @@ export class ElementNavComponent implements OnInit {
}

onJumpUi() {
window.open('/ui/', '_blank');
window.open(withUIBase(), '_blank');
}
}
3 changes: 2 additions & 1 deletion src/app/elements/nav/profile/profile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {HttpService} from '@app/services';
import {User} from '@app/globals';
import {User as ModelUser} from '@app/model';
import {withSitePrefix} from '@app/utils/path';

interface MenuItem {
id: string;
Expand Down Expand Up @@ -33,7 +34,7 @@ export class ElementUserFileComponent implements OnInit {
id: 'logout',
name: 'Log out',
click: () => {
window.location.href = document.location.origin + '/core/auth/logout/';
window.location.href = withSitePrefix('/core/auth/logout/');
},
}
];
Expand Down
4 changes: 2 additions & 2 deletions src/app/pages/kubernetes/kubernetes.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {AfterViewInit, Component, ElementRef, OnInit, ViewChild,} from '@angular
import {ActivatedRoute, Params} from '@angular/router';
import {HttpService, LogService, SettingService, ViewService} from '@app/services';
import {getWaterMarkContent} from '@app/utils/common';
import {withSitePrefix} from '@app/utils/path';

@Component({
standalone: false,
Expand All @@ -28,13 +29,12 @@ export class PagesKubernetesComponent implements OnInit, AfterViewInit {
this._settingSvc.createWaterMarkIfNeed(document.body, content);
});
this.id = 'window-' + Math.random().toString(36).substr(2);
const baseUrl = `${window.location.protocol}//${window.location.host}`;

this._route.params.subscribe((params: Params) => {
this.token = params['token'];
});

this.iframeURL = `${baseUrl}/koko/k8s/?token=${this.token}`;
this.iframeURL = withSitePrefix(`/koko/k8s/?token=${this.token}`);
}

ngAfterViewInit() {
Expand Down
10 changes: 3 additions & 7 deletions src/app/pages/main/main.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, HostListener, OnInit } from '@angular/core';
import { DataStore, User } from '@app/globals';
import { HttpService, LogService, SettingService, ViewService } from '@app/services';
import { environment } from '@src/environments/environment';
import { toAbsoluteWsUrl, withAppBase } from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -65,12 +66,7 @@ export class PageMainComponent implements OnInit {
onToggleMobileLayout() {}

connectWebsocket() {
const scheme = document.location.protocol === 'https:' ? 'wss' : 'ws';
const port = document.location.port ? ':' + document.location.port : '';
const url = '/ws/notifications/site-msg/';
const wsURL = scheme + '://' + document.location.hostname + port + url;

const ws = new WebSocket(wsURL);
const ws = new WebSocket(toAbsoluteWsUrl('/ws/notifications/site-msg/'));
ws.onopen = event => {
this._logger.debug('Websocket connected: ', event);
};
Expand All @@ -95,7 +91,7 @@ export class PageMainComponent implements OnInit {
}

const notInIframe = window.self === window.top;
const notInReplay = location.pathname.indexOf('/luna/replay') === -1;
const notInReplay = location.pathname.indexOf(withAppBase('/replay')) === -1;
const returnValue = !(notInIframe && notInReplay);
if (returnValue) {
$event.returnValue = true;
Expand Down
7 changes: 4 additions & 3 deletions src/app/pages/monitor/monitor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {ActivatedRoute} from '@angular/router';
import {Asset, Session, Ticket, User} from '@app/model';
import {NzNotificationService} from 'ng-zorro-antd/notification';
import {getWaterMarkContent} from '@app/utils/common';
import {joinEndpointUrl} from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -84,13 +85,13 @@ export class PagesMonitorComponent implements OnInit {
const terminal_type = this.sessionDetail.terminal.type;
switch (terminal_type) {
case 'razor':
this.iframeURL = `${baseUrl}/razor/monitor/${this.sessionID}/`;
this.iframeURL = joinEndpointUrl(baseUrl, `/razor/monitor/${this.sessionID}/`);
break;
case 'lion':
this.iframeURL = `${baseUrl}/lion/monitor/?session=${this.sessionID}`;
this.iframeURL = joinEndpointUrl(baseUrl, `/lion/monitor/?session=${this.sessionID}`);
break;
default:
this.iframeURL = `${baseUrl}/koko/monitor/${this.sessionID}/`;
this.iframeURL = joinEndpointUrl(baseUrl, `/koko/monitor/${this.sessionID}/`);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/app/pages/sftp/sftp.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser';
import {withSitePrefix} from '@app/utils/path';

@Component({
standalone: false,
Expand All @@ -16,6 +17,6 @@ export class PageSftpComponent implements OnInit {
}

ngOnInit() {
this.iframeURL = '/koko/elfinder/sftp/';
this.iframeURL = withSitePrefix('/koko/elfinder/sftp/');
}
}
7 changes: 4 additions & 3 deletions src/app/pages/share/share.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ActivatedRoute } from '@angular/router';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { withSitePrefix } from '@app/utils/path';

@Component({
standalone: false,
Expand Down Expand Up @@ -31,14 +32,14 @@ export class PagesShareComponent implements OnInit, AfterViewInit {
});

const queryString = queryParams.toString();
const baseUrl = `${window.location.protocol}//${window.location.host}`;
const querySuffix = queryString ? `?${queryString}` : '';

if (this.type && this.type === 'lion') {
this.iframeURL = `${baseUrl}/lion/share/${this.shareId}?${queryString}`;
this.iframeURL = withSitePrefix(`/lion/share/${this.shareId}${querySuffix}`);
return;
}

this.iframeURL = `${baseUrl}/koko/share/${this.shareId}?${queryString}`;
this.iframeURL = withSitePrefix(`/koko/share/${this.shareId}${querySuffix}`);
}

ngAfterViewInit(): void {
Expand Down
13 changes: 9 additions & 4 deletions src/app/services/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import { Account, Asset, AuthInfo, ConnectData, Endpoint, Organization, View } f
import * as CryptoJS from 'crypto-js';
import { OrganizationService } from './organization';
import { I18nService } from '@app/services/i18n';
import { getAppBasePath, getAppRoutePath, withSitePrefix } from '@app/utils/path';

declare function unescape(s: string): string;

function gotoLogin() {
const currentPath = encodeURI(document.location.pathname + document.location.search);
const loginUrl = new URL(withSitePrefix('/core/auth/login/'), document.location.origin);
loginUrl.searchParams.set('next', currentPath);
setTimeout(() => {
window.location.href = document.location.origin + '/core/auth/login/?next=' + currentPath;
window.location.href = loginUrl.toString();
}, 500);
}

Expand Down Expand Up @@ -114,7 +117,9 @@ export class AppService {
clearInterval(this.checkIntervalId);
const ok = confirm(this._i18n.instant(this.getErrorMsg(status)));
if (ok && !this.newLoginHasOpen) {
window.open('/core/auth/login/?next=/luna/', '_blank');
const loginUrl = new URL(withSitePrefix('/core/auth/login/'), window.location.origin);
loginUrl.searchParams.set('next', getAppBasePath());
window.open(loginUrl.toString(), '_blank');
this.newLoginHasOpen = true;
}
setTimeout(() => this.doCheckProfile(true), 5000);
Expand Down Expand Up @@ -159,10 +164,10 @@ export class AppService {
}

if (User.logined) {
if (document.location.pathname === '/login/') {
if (document.location.pathname === withSitePrefix('/login/')) {
this._router.navigate(['']);
} else {
this._router.navigate([document.location.pathname]);
this._router.navigateByUrl(getAppRoutePath(document.location.pathname));
}
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {NzNotificationService} from 'ng-zorro-antd/notification';
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
import {NZ_MODAL_DATA, NzModalRef, NzModalService} from 'ng-zorro-antd/modal';
import {ActivatedRoute} from '@angular/router';
import {withUIBase} from '@app/utils/path';

interface DialogAction {
text: string;
Expand Down Expand Up @@ -394,7 +395,7 @@ export class ElementACLDialogComponent implements OnInit {
isError: true,
customContent: {
type: 'link',
link: '/ui/#/profile/index',
link: withUIBase('#/profile/index'),
linkText: this._i18n.instant('Go to profile')
},
actions: [
Expand Down
Loading
Loading