Merge branch 'next' into dependabot/npm_and_yarn/frontend/minimatch-3.1.5
This commit is contained in:
commit
e8e62d22f1
|
|
@ -10,6 +10,7 @@
|
|||
[](https://bestpractices.coreinfrastructure.org/projects/5050)
|
||||
|
||||
[](https://goreportcard.com/report/github.com/OliveTin/OliveTin)
|
||||
[-blue)](https://blog.jread.com/posts/ai-levels-of-autonomy-in-software-engineering/)
|
||||
|
||||
[OliveTin 2k to 3k upgrade guide](https://docs.olivetin.app/upgrade/2k3k.html)
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Terminal } from '@xterm/xterm'
|
||||
import { FitAddon } from '@xterm/addon-fit'
|
||||
import { WebLinksAddon } from '@xterm/addon-web-links'
|
||||
import { Mutex } from './Mutex.js'
|
||||
|
||||
/**
|
||||
|
|
@ -18,13 +19,24 @@ export class OutputTerminal {
|
|||
constructor (executionTrackingId) {
|
||||
this.executionTrackingId = executionTrackingId
|
||||
this.writeMutex = new Mutex()
|
||||
const linkHandler = {
|
||||
activate (event, text, _range) {
|
||||
event.preventDefault()
|
||||
window.open(text, '_blank')
|
||||
}
|
||||
}
|
||||
|
||||
this.terminal = new Terminal({
|
||||
convertEol: true
|
||||
convertEol: true,
|
||||
linkHandler
|
||||
})
|
||||
|
||||
const fitAddon = new FitAddon()
|
||||
this.terminal.loadAddon(fitAddon)
|
||||
this.terminal.fit = fitAddon
|
||||
|
||||
this.terminal.loadAddon(new WebLinksAddon((event, uri) => linkHandler.activate(event, uri)))
|
||||
this.linkHandlerConfigured = true
|
||||
}
|
||||
|
||||
async write (out, then) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
"@hugeicons/vue": "^1.0.4",
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/addon-web-links": "^0.12.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"iconify-icon": "^3.0.2",
|
||||
"picocrank": "^1.14.0",
|
||||
|
|
@ -1570,6 +1571,12 @@
|
|||
"integrity": "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@xterm/addon-web-links": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@xterm/addon-web-links/-/addon-web-links-0.12.0.tgz",
|
||||
"integrity": "sha512-4Smom3RPyVp7ZMYOYDoC/9eGJJJqYhnPLGGqJ6wOBfB8VxPViJNSKdgRYb8NpaM6YSelEKbA2SStD7lGyqaobw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@xterm/xterm": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-6.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -28,13 +28,14 @@
|
|||
"@hugeicons/vue": "^1.0.4",
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/addon-web-links": "^0.12.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"iconify-icon": "^3.0.2",
|
||||
"picocrank": "^1.14.0",
|
||||
"standard": "^17.1.2",
|
||||
"unplugin-vue-components": "^31.0.0",
|
||||
"vite": "^7.3.1",
|
||||
"vue": "^3.5.29",
|
||||
"vue": "^3.5.29",
|
||||
"vue-i18n": "^11.2.8",
|
||||
"vue-router": "^5.0.3"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,6 +210,11 @@ export declare type EffectivePolicy = Message<"olivetin.api.v1.EffectivePolicy">
|
|||
* @generated from field: bool show_log_list = 2;
|
||||
*/
|
||||
showLogList: boolean;
|
||||
|
||||
/**
|
||||
* @generated from field: bool show_version_number = 3;
|
||||
*/
|
||||
showVersionNumber: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1853,4 +1858,3 @@ export declare const OliveTinApiService: GenService<{
|
|||
output: typeof EntitySchema;
|
||||
},
|
||||
}>;
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -31,7 +31,7 @@
|
|||
<footer title="footer" v-if="showFooter">
|
||||
<p>
|
||||
<img title="application icon" :src="logoUrl" alt="OliveTin logo" style="height: 1em;" class="logo" />
|
||||
OliveTin {{ currentVersion }}
|
||||
OliveTin <span v-if="showVersionNumber">{{ currentVersion }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
<span>{{ t('connected') }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<p v-if="showVersionNumber">
|
||||
<a id="available-version" href="http://olivetin.app" target="_blank" hidden>?</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
|
@ -126,6 +126,7 @@ const showFooter = ref(true)
|
|||
const showNavigation = ref(true)
|
||||
const showLogs = ref(true)
|
||||
const showDiagnostics = ref(true)
|
||||
const showVersionNumber = ref(true)
|
||||
const showLoginLink = ref(true)
|
||||
const sectionNavigationStyle = ref('sidebar')
|
||||
|
||||
|
|
@ -223,6 +224,7 @@ function updateHeaderFromInit() {
|
|||
showNavigation.value = window.initResponse.showNavigation
|
||||
showLogs.value = window.initResponse.showLogList
|
||||
showDiagnostics.value = window.initResponse.showDiagnostics
|
||||
showVersionNumber.value = window.initResponse.effectivePolicy?.showVersionNumber ?? true
|
||||
sectionNavigationStyle.value = window.initResponse.sectionNavigationStyle || 'sidebar'
|
||||
availableThemes.value = window.initResponse.availableThemes || []
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,10 @@ async function generateBrowserInfo() {
|
|||
userAgentData: userAgentData
|
||||
}
|
||||
|
||||
const olivetinVersion = window.initResponse?.currentVersion || t('diagnostics.unknown')
|
||||
const showVersionNumber = window.initResponse?.effectivePolicy?.showVersionNumber ?? true
|
||||
const olivetinVersion = showVersionNumber
|
||||
? (window.initResponse?.currentVersion || t('diagnostics.unknown'))
|
||||
: '[hidden]'
|
||||
const currentLanguage = locale.value || t('diagnostics.unknown')
|
||||
|
||||
let output = '';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Integration Test Config: xterm link handling
|
||||
#
|
||||
|
||||
listenAddressSingleHTTPFrontend: 0.0.0.0:1337
|
||||
|
||||
logLevel: "DEBUG"
|
||||
checkForUpdates: false
|
||||
|
||||
actions:
|
||||
- title: Echo URL
|
||||
shell: echo "See https://example.com for more info"
|
||||
popupOnStart: execution-dialog-stdout-only
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
import { describe, it, before, after } from 'mocha'
|
||||
import { expect } from 'chai'
|
||||
import { By, Condition } from 'selenium-webdriver'
|
||||
import {
|
||||
getRootAndWait,
|
||||
takeScreenshotOnFailure,
|
||||
getTerminalBuffer,
|
||||
} from '../../lib/elements.js'
|
||||
|
||||
describe('config: xtermLinkHandling', function () {
|
||||
before(async function () {
|
||||
await runner.start('xtermLinkHandling')
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await runner.stop()
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
takeScreenshotOnFailure(this.currentTest, webdriver)
|
||||
})
|
||||
|
||||
it('xterm output shows URL and link handling is configured', async function () {
|
||||
await getRootAndWait()
|
||||
|
||||
await webdriver.wait(new Condition('wait for Echo URL button', async () => {
|
||||
const btns = await webdriver.findElements(By.css('[title="Echo URL"]'))
|
||||
return btns.length === 1
|
||||
}), 10000)
|
||||
|
||||
const echoUrlButton = await webdriver.findElement(By.css('[title="Echo URL"]'))
|
||||
await echoUrlButton.click()
|
||||
|
||||
await webdriver.wait(new Condition('wait for execution view', async () => {
|
||||
const url = await webdriver.getCurrentUrl()
|
||||
return url.includes('/logs/') && !url.endsWith('/logs')
|
||||
}), 10000)
|
||||
|
||||
await webdriver.wait(new Condition('wait for execution status', async () => {
|
||||
const statusElements = await webdriver.findElements(By.id('execution-dialog-status'))
|
||||
return statusElements.length > 0
|
||||
}), 5000)
|
||||
|
||||
await webdriver.wait(new Condition('wait for execution to finish', async () => {
|
||||
try {
|
||||
const statusElement = await webdriver.findElement(By.id('execution-dialog-status'))
|
||||
const statusText = await statusElement.getText()
|
||||
return !statusText.includes('Executing')
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}), 5000)
|
||||
|
||||
await webdriver.sleep(500)
|
||||
|
||||
const bufferText = await getTerminalBuffer()
|
||||
expect(bufferText).to.not.be.null
|
||||
expect(bufferText).to.include('https://example.com')
|
||||
|
||||
const linkHandlerSet = await webdriver.executeScript(`
|
||||
try {
|
||||
return !!(window.terminal && window.terminal.linkHandlerConfigured === true)
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
`)
|
||||
expect(linkHandlerSet).to.equal(true)
|
||||
})
|
||||
})
|
||||
|
|
@ -51,6 +51,7 @@ message GetDashboardResponse {
|
|||
message EffectivePolicy {
|
||||
bool show_diagnostics = 1;
|
||||
bool show_log_list = 2;
|
||||
bool show_version_number = 3;
|
||||
}
|
||||
|
||||
message GetDashboardRequest {
|
||||
|
|
|
|||
|
|
@ -410,11 +410,12 @@ func (x *GetDashboardResponse) GetDashboard() *Dashboard {
|
|||
}
|
||||
|
||||
type EffectivePolicy struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ShowDiagnostics bool `protobuf:"varint,1,opt,name=show_diagnostics,json=showDiagnostics,proto3" json:"show_diagnostics,omitempty"`
|
||||
ShowLogList bool `protobuf:"varint,2,opt,name=show_log_list,json=showLogList,proto3" json:"show_log_list,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ShowDiagnostics bool `protobuf:"varint,1,opt,name=show_diagnostics,json=showDiagnostics,proto3" json:"show_diagnostics,omitempty"`
|
||||
ShowLogList bool `protobuf:"varint,2,opt,name=show_log_list,json=showLogList,proto3" json:"show_log_list,omitempty"`
|
||||
ShowVersionNumber bool `protobuf:"varint,3,opt,name=show_version_number,json=showVersionNumber,proto3" json:"show_version_number,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EffectivePolicy) Reset() {
|
||||
|
|
@ -461,6 +462,13 @@ func (x *EffectivePolicy) GetShowLogList() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (x *EffectivePolicy) GetShowVersionNumber() bool {
|
||||
if x != nil {
|
||||
return x.ShowVersionNumber
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type GetDashboardRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
|
||||
|
|
@ -3934,10 +3942,11 @@ const file_olivetin_api_v1_olivetin_proto_rawDesc = "" +
|
|||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"f\n" +
|
||||
"\x14GetDashboardResponse\x12\x14\n" +
|
||||
"\x05title\x18\x01 \x01(\tR\x05title\x128\n" +
|
||||
"\tdashboard\x18\x04 \x01(\v2\x1a.olivetin.api.v1.DashboardR\tdashboard\"`\n" +
|
||||
"\tdashboard\x18\x04 \x01(\v2\x1a.olivetin.api.v1.DashboardR\tdashboard\"\x90\x01\n" +
|
||||
"\x0fEffectivePolicy\x12)\n" +
|
||||
"\x10show_diagnostics\x18\x01 \x01(\bR\x0fshowDiagnostics\x12\"\n" +
|
||||
"\rshow_log_list\x18\x02 \x01(\bR\vshowLogList\"k\n" +
|
||||
"\rshow_log_list\x18\x02 \x01(\bR\vshowLogList\x12.\n" +
|
||||
"\x13show_version_number\x18\x03 \x01(\bR\x11showVersionNumber\"k\n" +
|
||||
"\x13GetDashboardRequest\x12\x14\n" +
|
||||
"\x05title\x18\x01 \x01(\tR\x05title\x12\x1f\n" +
|
||||
"\ventity_type\x18\x02 \x01(\tR\n" +
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module github.com/OliveTin/OliveTin
|
||||
|
||||
go 1.25.0
|
||||
go 1.25.6
|
||||
|
||||
exclude google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ require (
|
|||
github.com/MicahParks/keyfunc/v3 v3.8.0
|
||||
github.com/PaesslerAG/jsonpath v0.1.1
|
||||
github.com/alexedwards/argon2id v1.0.0
|
||||
github.com/bufbuild/buf v1.65.0
|
||||
github.com/bufbuild/buf v1.66.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/fzipp/gocyclo v0.6.0
|
||||
github.com/go-critic/go-critic v0.14.3
|
||||
|
|
@ -27,7 +27,7 @@ require (
|
|||
github.com/sirupsen/logrus v1.9.4
|
||||
github.com/stretchr/testify v1.11.1
|
||||
go.akshayshah.org/connectproto v0.6.0
|
||||
golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa
|
||||
golang.org/x/oauth2 v0.35.0
|
||||
golang.org/x/sys v0.41.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
|
|
@ -45,7 +45,7 @@ require (
|
|||
buf.build/go/bufplugin v0.9.0 // indirect
|
||||
buf.build/go/bufprivateusage v0.1.0 // indirect
|
||||
buf.build/go/interrupt v1.1.0 // indirect
|
||||
buf.build/go/protovalidate v1.1.2 // indirect
|
||||
buf.build/go/protovalidate v1.1.3 // indirect
|
||||
buf.build/go/protoyaml v0.6.0 // indirect
|
||||
buf.build/go/spdx v0.2.0 // indirect
|
||||
buf.build/go/standard v0.1.0 // indirect
|
||||
|
|
@ -57,7 +57,7 @@ require (
|
|||
github.com/PaesslerAG/gval v1.2.4 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260130195850-5c64bed4577e // indirect
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260202185951-d02d3732d113 // indirect
|
||||
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cli/browser v1.3.0 // indirect
|
||||
|
|
@ -90,7 +90,7 @@ require (
|
|||
github.com/gofrs/flock v0.13.0 // indirect
|
||||
github.com/google/cel-go v0.27.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-containerregistry v0.20.7 // indirect
|
||||
github.com/google/go-containerregistry v0.21.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jdx/go-netrc v1.0.0 // indirect
|
||||
|
|
@ -155,8 +155,8 @@ require (
|
|||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.42.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/grpc v1.75.1 // indirect
|
||||
mvdan.cc/xurls/v2 v2.6.0 // indirect
|
||||
pluginrpc.com/pluginrpc v0.5.0 // indirect
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ buf.build/go/protovalidate v1.1.0 h1:pQqEQRpOo4SqS60qkvmhLTTQU9JwzEvdyiqAtXa5SeY
|
|||
buf.build/go/protovalidate v1.1.0/go.mod h1:bGZcPiAQDC3ErCHK3t74jSoJDFOs2JH3d7LWuTEIdss=
|
||||
buf.build/go/protovalidate v1.1.2 h1:83vYHoY8f34hB8MeitGaYE3CGVPFxwdEUuskh5qQpA0=
|
||||
buf.build/go/protovalidate v1.1.2/go.mod h1:Ez3z+w4c+wG+EpW8ovgZaZPnPl2XVF6kaxgcv1NG/QE=
|
||||
buf.build/go/protovalidate v1.1.3 h1:m2GVEgQWd7rk+vIoAZ+f0ygGjvQTuqPQapBBdcpWVPE=
|
||||
buf.build/go/protovalidate v1.1.3/go.mod h1:9XIuohWz+kj+9JVn3WQneHA5LZP50mjvneZMnbLkiIE=
|
||||
buf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w=
|
||||
buf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q=
|
||||
buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw=
|
||||
|
|
@ -84,6 +86,8 @@ github.com/bufbuild/buf v1.64.0 h1:puHWFcVKmZFSu4KuaN0kZiQ32n7VVc3un1FeLU77XUs=
|
|||
github.com/bufbuild/buf v1.64.0/go.mod h1:U4ISwkjZXRLMaCkPG9zp1xY3xHEIwhCFwyNAaA56SGw=
|
||||
github.com/bufbuild/buf v1.65.0 h1:f2BzeCY9rRh9P5KD340ZoPAaFLTkssoUTHx7lpqozgg=
|
||||
github.com/bufbuild/buf v1.65.0/go.mod h1:7SAs2YqGpPXHqBBXBeYQbCzY0OQq4Jbg6XCqirEiYvQ=
|
||||
github.com/bufbuild/buf v1.66.0 h1:6kksYJpu6r45bvPJSTwNSwRqiAjrwB9YyU7skjNzFVo=
|
||||
github.com/bufbuild/buf v1.66.0/go.mod h1:tWVlwtIPZ7kzlCB9D0hbbfrroT0GNCybPdPQXq1i1Ac=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20251223142729-db46c1b9d34e h1:LQA+1MyiPkolGHJGC2GMDC5Xu+0RDVH6jGMKech7Exs=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20251223142729-db46c1b9d34e/go.mod h1:5UUj46Eu+U+C59C5N6YilaMI7WWfP2bW9xGcOkme2DI=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260105175043-4d8d90b1c6b8 h1:cQYwUyAzyMmYr7AyJU1C6pVCpUrJJBkmx7UunZosxxs=
|
||||
|
|
@ -92,6 +96,8 @@ github.com/bufbuild/protocompile v0.14.2-0.20260120135352-a3ed5cd7a608 h1:3aRREB
|
|||
github.com/bufbuild/protocompile v0.14.2-0.20260120135352-a3ed5cd7a608/go.mod h1:5UUj46Eu+U+C59C5N6YilaMI7WWfP2bW9xGcOkme2DI=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260130195850-5c64bed4577e h1:emH16Bf1w4C0cJ3ge4QtBAl4sIYJe23EfpWH0SpA9co=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260130195850-5c64bed4577e/go.mod h1:cxhE8h+14t0Yxq2H9MV/UggzQ1L0gh0t2tJobITWsBE=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260202185951-d02d3732d113 h1:nxt1QhP9rMQNFhHTdcNFwJ9wKCSdBjd28gz+qGDv4kM=
|
||||
github.com/bufbuild/protocompile v0.14.2-0.20260202185951-d02d3732d113/go.mod h1:cxhE8h+14t0Yxq2H9MV/UggzQ1L0gh0t2tJobITWsBE=
|
||||
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLqVg44rY97xOR+mQpD2N+GzhMHVwJ030WEU=
|
||||
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
|
|
@ -200,6 +206,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
|||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=
|
||||
github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM=
|
||||
github.com/google/go-containerregistry v0.21.0 h1:ocqxUOczFwAZQBMNE7kuzfqvDe0VWoZxQMOesXreCDI=
|
||||
github.com/google/go-containerregistry v0.21.0/go.mod h1:ctO5aCaewH4AK1AumSF5DPW+0+R+d2FmylMJdp5G7p0=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg=
|
||||
|
|
@ -375,6 +383,7 @@ go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIl
|
|||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
|
|
@ -421,6 +430,8 @@ golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7
|
|||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
|
||||
golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o=
|
||||
golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20251219203646-944ab1f22d93 h1:PbC785RGO6yPO051ItgbG/adwoKRWC0VS7kXXeD/iqk=
|
||||
|
|
@ -519,6 +530,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260122232226-8e98ce8d340d h1:
|
|||
google.golang.org/genproto/googleapis/api v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
|
||||
|
|
@ -527,6 +540,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d h1:
|
|||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
|
|
|
|||
|
|
@ -710,7 +710,9 @@ func (api *oliveTinAPI) WhoAmI(ctx ctx.Context, req *connect.Request[apiv1.WhoAm
|
|||
}
|
||||
|
||||
func (api *oliveTinAPI) SosReport(ctx ctx.Context, req *connect.Request[apiv1.SosReportRequest]) (*connect.Response[apiv1.SosReportResponse], error) {
|
||||
sos := installationinfo.GetSosReport()
|
||||
user := auth.UserFromApiCall(ctx, req, api.cfg)
|
||||
redactVersion := !user.EffectivePolicy.ShowVersionNumber
|
||||
sos := installationinfo.GetSosReport(redactVersion)
|
||||
|
||||
if !api.cfg.InsecureAllowDumpSos {
|
||||
log.Info(sos)
|
||||
|
|
@ -914,12 +916,19 @@ func (api *oliveTinAPI) Init(ctx ctx.Context, req *connect.Request[apiv1.InitReq
|
|||
|
||||
loginRequired := user.IsGuest() && api.cfg.AuthRequireGuestsToLogin
|
||||
|
||||
showVersion := user.EffectivePolicy.ShowVersionNumber
|
||||
currentVersion := ""
|
||||
availableVersion := ""
|
||||
if showVersion {
|
||||
currentVersion = installationinfo.Build.Version
|
||||
availableVersion = installationinfo.Runtime.AvailableVersion
|
||||
}
|
||||
res := &apiv1.InitResponse{
|
||||
ShowFooter: api.cfg.ShowFooter,
|
||||
ShowNavigation: api.cfg.ShowNavigation,
|
||||
ShowNewVersions: api.cfg.ShowNewVersions,
|
||||
AvailableVersion: installationinfo.Runtime.AvailableVersion,
|
||||
CurrentVersion: installationinfo.Build.Version,
|
||||
ShowNewVersions: showVersion && api.cfg.ShowNewVersions,
|
||||
AvailableVersion: availableVersion,
|
||||
CurrentVersion: currentVersion,
|
||||
PageTitle: api.cfg.PageTitle,
|
||||
SectionNavigationStyle: api.cfg.SectionNavigationStyle,
|
||||
DefaultIconForBack: api.cfg.DefaultIconForBack,
|
||||
|
|
|
|||
|
|
@ -55,8 +55,9 @@ func matchesEntity(binding *executor.ActionBinding, entity *entities.Entity) boo
|
|||
|
||||
func buildEffectivePolicy(policy *config.ConfigurationPolicy) *apiv1.EffectivePolicy {
|
||||
ret := &apiv1.EffectivePolicy{
|
||||
ShowDiagnostics: policy.ShowDiagnostics,
|
||||
ShowLogList: policy.ShowLogList,
|
||||
ShowDiagnostics: policy.ShowDiagnostics,
|
||||
ShowLogList: policy.ShowLogList,
|
||||
ShowVersionNumber: policy.ShowVersionNumber,
|
||||
}
|
||||
|
||||
return ret
|
||||
|
|
|
|||
|
|
@ -76,8 +76,9 @@ func (u *AuthenticatedUser) BuildUserAcls(cfg *config.Config) {
|
|||
|
||||
func getEffectivePolicy(cfg *config.Config, u *AuthenticatedUser) *config.ConfigurationPolicy {
|
||||
ret := &config.ConfigurationPolicy{
|
||||
ShowDiagnostics: cfg.DefaultPolicy.ShowDiagnostics,
|
||||
ShowLogList: cfg.DefaultPolicy.ShowLogList,
|
||||
ShowDiagnostics: cfg.DefaultPolicy.ShowDiagnostics,
|
||||
ShowLogList: cfg.DefaultPolicy.ShowLogList,
|
||||
ShowVersionNumber: cfg.DefaultPolicy.ShowVersionNumber,
|
||||
}
|
||||
|
||||
for _, acl := range cfg.AccessControlLists {
|
||||
|
|
@ -98,5 +99,9 @@ func buildConfigurationPolicy(ret *config.ConfigurationPolicy, policy config.Con
|
|||
ret.ShowLogList = policy.ShowLogList
|
||||
}
|
||||
|
||||
if policy.ShowVersionNumber {
|
||||
ret.ShowVersionNumber = policy.ShowVersionNumber
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
authTypes "github.com/OliveTin/OliveTin/internal/auth/authpublic"
|
||||
|
|
@ -21,6 +22,7 @@ import (
|
|||
|
||||
type OAuth2Handler struct {
|
||||
cfg *config.Config
|
||||
mu sync.RWMutex
|
||||
registeredStates map[string]*oauth2State
|
||||
registeredProviders map[string]*oauth2.Config
|
||||
}
|
||||
|
|
@ -144,11 +146,13 @@ func (h *OAuth2Handler) HandleOAuthLogin(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
h.mu.Lock()
|
||||
h.registeredStates[state] = &oauth2State{
|
||||
providerConfig: provider,
|
||||
providerName: providerName,
|
||||
Username: "",
|
||||
}
|
||||
h.mu.Unlock()
|
||||
|
||||
h.setOAuthCallbackCookie(w, r, "olivetin-sid-oauth", state)
|
||||
|
||||
|
|
@ -177,7 +181,9 @@ func (h *OAuth2Handler) checkOAuthCallbackCookie(w http.ResponseWriter, r *http.
|
|||
return nil, state, false
|
||||
}
|
||||
|
||||
h.mu.RLock()
|
||||
registeredState, ok := h.registeredStates[state]
|
||||
h.mu.RUnlock()
|
||||
if !ok {
|
||||
log.Errorf("State not found in server: %v", state)
|
||||
http.Error(w, "State not found in server", http.StatusBadRequest)
|
||||
|
|
@ -287,8 +293,10 @@ func (h *OAuth2Handler) HandleOAuthCallback(w http.ResponseWriter, r *http.Reque
|
|||
userInfoClient := h.createUserInfoClient(ctx, registeredState.providerConfig, tok, clientSettings)
|
||||
userinfo := getUserInfo(h.cfg, userInfoClient, providerConfig)
|
||||
|
||||
h.mu.Lock()
|
||||
h.registeredStates[state].Username = userinfo.Username
|
||||
h.registeredStates[state].Usergroup = h.computeUsergroup(userinfo, providerConfig)
|
||||
h.mu.Unlock()
|
||||
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
}
|
||||
|
|
@ -366,34 +374,36 @@ func getDataField(data map[string]any, field string) string {
|
|||
return stringVal
|
||||
}
|
||||
|
||||
func (h *OAuth2Handler) lookupOAuth2UserByState(state string) (*authTypes.AuthenticatedUser, bool) {
|
||||
h.mu.RLock()
|
||||
serverState, found := h.registeredStates[state]
|
||||
if !found {
|
||||
h.mu.RUnlock()
|
||||
return nil, false
|
||||
}
|
||||
user := &authTypes.AuthenticatedUser{
|
||||
Username: serverState.Username,
|
||||
UsergroupLine: serverState.Usergroup,
|
||||
Provider: "oauth2",
|
||||
SID: state,
|
||||
}
|
||||
h.mu.RUnlock()
|
||||
return user, true
|
||||
}
|
||||
|
||||
func (h *OAuth2Handler) CheckUserFromOAuth2Cookie(context *authTypes.AuthCheckingContext) *authTypes.AuthenticatedUser {
|
||||
cookie, err := context.Request.Cookie("olivetin-sid-oauth")
|
||||
|
||||
user := &authTypes.AuthenticatedUser{}
|
||||
|
||||
if err != nil {
|
||||
if err != nil || cookie.Value == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if cookie.Value == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
serverState, found := h.registeredStates[cookie.Value]
|
||||
|
||||
user, found := h.lookupOAuth2UserByState(cookie.Value)
|
||||
if !found {
|
||||
log.WithFields(log.Fields{
|
||||
"sid": cookie.Value,
|
||||
"provider": "oauth2",
|
||||
}).Warnf("Stale session")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
user.Username = serverState.Username
|
||||
user.UsergroupLine = serverState.Usergroup
|
||||
user.Provider = "oauth2"
|
||||
user.SID = cookie.Value
|
||||
|
||||
return user
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,9 @@ type AccessControlList struct {
|
|||
|
||||
// ConfigurationPolicy defines global settings which are overridden with an ACL.
|
||||
type ConfigurationPolicy struct {
|
||||
ShowDiagnostics bool `koanf:"showDiagnostics"`
|
||||
ShowLogList bool `koanf:"showLogList"`
|
||||
ShowDiagnostics bool `koanf:"showDiagnostics"`
|
||||
ShowLogList bool `koanf:"showLogList"`
|
||||
ShowVersionNumber bool `koanf:"showVersionNumber"`
|
||||
}
|
||||
|
||||
type PrometheusConfig struct {
|
||||
|
|
@ -297,6 +298,7 @@ func DefaultConfigWithBasePort(basePort int) *Config {
|
|||
|
||||
config.DefaultPolicy.ShowDiagnostics = true
|
||||
config.DefaultPolicy.ShowLogList = true
|
||||
config.DefaultPolicy.ShowVersionNumber = true
|
||||
|
||||
return &config
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ func (cfg *Config) sanitizeAuthRequireGuestsToLogin() {
|
|||
cfg.DefaultPermissions.View = false
|
||||
cfg.DefaultPermissions.Exec = false
|
||||
cfg.DefaultPermissions.Logs = false
|
||||
cfg.DefaultPermissions.Kill = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,15 +40,23 @@ func configToSosreport(cfg *config.Config) *sosReportConfig {
|
|||
}
|
||||
}
|
||||
|
||||
func GetSosReport() string {
|
||||
func GetSosReport(redactVersion bool) string {
|
||||
ret := ""
|
||||
|
||||
ret += "### SOSREPORT START (copy all text to SOSREPORT END)\n"
|
||||
|
||||
out, _ := yaml.Marshal(Build)
|
||||
buildForReport := *Build
|
||||
if redactVersion {
|
||||
buildForReport.Version = "[redacted]"
|
||||
}
|
||||
out, _ := yaml.Marshal(&buildForReport)
|
||||
ret += fmt.Sprintf("# Build: \n%+v\n", string(out))
|
||||
|
||||
out, _ = yaml.Marshal(Runtime)
|
||||
runtimeForReport := *Runtime
|
||||
if redactVersion {
|
||||
runtimeForReport.AvailableVersion = "[redacted]"
|
||||
}
|
||||
out, _ = yaml.Marshal(&runtimeForReport)
|
||||
ret += fmt.Sprintf("# Runtime:\n%+v\n", string(out))
|
||||
|
||||
out, _ = yaml.Marshal(configToSosreport(Config))
|
||||
|
|
|
|||
Loading…
Reference in New Issue