Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package semaphore for openSUSE:Factory 
checked in at 2026-07-23 23:10:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/semaphore (Old)
 and      /work/SRC/openSUSE:Factory/.semaphore.new.2004 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "semaphore"

Thu Jul 23 23:10:57 2026 rev:53 rq:1367311 version:2.18.28

Changes:
--------
--- /work/SRC/openSUSE:Factory/semaphore/semaphore.changes      2026-07-14 
13:52:07.795517240 +0200
+++ /work/SRC/openSUSE:Factory/.semaphore.new.2004/semaphore.changes    
2026-07-23 23:14:18.368627877 +0200
@@ -1,0 +2,10 @@
+Thu Jul 23 06:03:14 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 2.18.28:
+  * Bugfixes
+    - Validate schedule cron format using backend endpoint instead
+      of JS library
+- Update to version 2.18.27:
+  * fix(templates): validate app
+
+-------------------------------------------------------------------

Old:
----
  semaphore-2.18.26.obscpio
  web-2.18.26.tar.gz

New:
----
  semaphore-2.18.28.obscpio
  web-2.18.28.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ semaphore.spec ++++++
--- /var/tmp/diff_new_pack.0XE2VV/_old  2026-07-23 23:14:22.864785988 +0200
+++ /var/tmp/diff_new_pack.0XE2VV/_new  2026-07-23 23:14:22.864785988 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           semaphore
-Version:        2.18.26
+Version:        2.18.28
 Release:        0
 Summary:        Modern UI for Ansible
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.0XE2VV/_old  2026-07-23 23:14:22.928788238 +0200
+++ /var/tmp/diff_new_pack.0XE2VV/_new  2026-07-23 23:14:22.932788379 +0200
@@ -3,7 +3,7 @@
     <param 
name="url">https://github.com/ansible-semaphore/semaphore.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">refs/tags/v2.18.26</param>
+    <param name="revision">refs/tags/v2.18.28</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.0XE2VV/_old  2026-07-23 23:14:22.960789364 +0200
+++ /var/tmp/diff_new_pack.0XE2VV/_new  2026-07-23 23:14:22.964789504 +0200
@@ -3,6 +3,6 @@
                 <param 
name="url">https://github.com/ansible-semaphore/semaphore</param>
               <param 
name="changesrevision">8a4dcf0868af718aaa5871368a3247dd622521f4</param></service><service
 name="tar_scm">
                 <param 
name="url">https://github.com/ansible-semaphore/semaphore.git</param>
-              <param 
name="changesrevision">ee781a032ccb58c61de6b9a70993f9b6dc77dcf8</param></service></servicedata>
+              <param 
name="changesrevision">33874e063dd9d7dc441e11f7fbfc24c0c28b270f</param></service></servicedata>
 (No newline at EOF)
 

++++++ semaphore-2.18.26.obscpio -> semaphore-2.18.28.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semaphore-2.18.26/api/projects/templates.go 
new/semaphore-2.18.28/api/projects/templates.go
--- old/semaphore-2.18.26/api/projects/templates.go     2026-07-12 
13:37:09.000000000 +0200
+++ new/semaphore-2.18.28/api/projects/templates.go     2026-07-22 
14:24:43.000000000 +0200
@@ -106,11 +106,6 @@
                return
        }
 
-       if _, ok := util.Config.Apps[string(newTemplate.App)]; !ok {
-               helpers.WriteErrorStatus(w, "Invalid app id: 
"+string(newTemplate.App), http.StatusBadRequest)
-               return
-       }
-
        // Check workspace and create it if required.
        if newTemplate.App.IsTerraform() {
                var inv db.Inventory
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semaphore-2.18.26/db/Template.go 
new/semaphore-2.18.28/db/Template.go
--- old/semaphore-2.18.26/db/Template.go        2026-07-12 13:37:09.000000000 
+0200
+++ new/semaphore-2.18.28/db/Template.go        2026-07-22 14:24:43.000000000 
+0200
@@ -4,6 +4,7 @@
        "encoding/json"
 
        "github.com/semaphoreui/semaphore/pkg/common_errors"
+       "github.com/semaphoreui/semaphore/util"
        log "github.com/sirupsen/logrus"
 )
 
@@ -212,6 +213,17 @@
        if tpl.RunnerTag != nil && *tpl.RunnerTag == "" {
                return &ValidationError{"template runner tag can not be empty"}
        }
+
+       // Reject apps that are not in the administrator-configured whitelist, 
otherwise
+       // an unknown app becomes a ShellApp that executes string(App) as a 
system binary
+       // (arbitrary command execution). util.Config is nil in some unit 
tests; an empty
+       // app is the legacy default and runs no command, so both are skipped.
+       if tpl.App != "" {
+               if _, ok := util.Config.Apps[string(tpl.App)]; !ok {
+                       return &ValidationError{"invalid app: " + 
string(tpl.App)}
+               }
+       }
+
        switch tpl.App {
        case AppAnsible:
                if tpl.InventoryID == nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semaphore-2.18.26/db/Template_app_test.go 
new/semaphore-2.18.28/db/Template_app_test.go
--- old/semaphore-2.18.26/db/Template_app_test.go       1970-01-01 
01:00:00.000000000 +0100
+++ new/semaphore-2.18.28/db/Template_app_test.go       2026-07-22 
14:24:43.000000000 +0200
@@ -0,0 +1,29 @@
+package db
+
+import (
+       "testing"
+
+       "github.com/semaphoreui/semaphore/util"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestTemplate_Validate_App(t *testing.T) {
+       orig := util.Config
+       defer func() { util.Config = orig }()
+
+       util.Config = &util.ConfigType{
+               Apps: map[string]util.App{"bash": {Active: true}},
+       }
+
+       // Arbitrary binary not in the whitelist must be rejected before 
persisting.
+       tpl := &Template{Name: "rce", Playbook: "-c", App: "/bin/sh"}
+       assert.EqualError(t, tpl.Validate(), "invalid app: /bin/sh")
+
+       // Whitelisted app is accepted.
+       ok := &Template{Name: "legit", Playbook: "script.sh", App: "bash"}
+       assert.NoError(t, ok.Validate())
+
+       // Empty legacy app runs no command and stays allowed.
+       empty := &Template{Name: "legacy", Playbook: "site.yml", App: ""}
+       assert.NoError(t, empty.Validate())
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semaphore-2.18.26/db/sql/SqlDb.go 
new/semaphore-2.18.28/db/sql/SqlDb.go
--- old/semaphore-2.18.26/db/sql/SqlDb.go       2026-07-12 13:37:09.000000000 
+0200
+++ new/semaphore-2.18.28/db/sql/SqlDb.go       2026-07-22 14:24:43.000000000 
+0200
@@ -105,6 +105,9 @@
 }
 
 func (d *SqlDbConnection) Close() {
+       if d.sql.Db == nil {
+               return
+       }
        err := d.sql.Db.Close()
        if err != nil {
                panic(err)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/semaphore-2.18.26/web/src/components/ScheduleForm.vue 
new/semaphore-2.18.28/web/src/components/ScheduleForm.vue
--- old/semaphore-2.18.26/web/src/components/ScheduleForm.vue   2026-07-12 
13:37:09.000000000 +0200
+++ new/semaphore-2.18.28/web/src/components/ScheduleForm.vue   2026-07-22 
14:24:43.000000000 +0200
@@ -607,7 +607,24 @@
       }
     },
 
-    refreshCheckboxes() {
+    async validateCronFormat(cronFormat) {
+      try {
+        await axios({
+          method: 'post',
+          url: `/api/project/${this.projectId}/schedules/validate`,
+          responseType: 'json',
+          data: {
+            project_id: this.projectId,
+            cron_format: cronFormat,
+          },
+        });
+        return null;
+      } catch (err) {
+        return getErrorMessage(err);
+      }
+    },
+
+    async refreshCheckboxes() {
       if (this.type === 'run_at') {
         this.cronFormatError = null;
         this.disableRawCron = false;
@@ -624,13 +641,28 @@
       this.cronFormatError = null;
       this.disableRawCron = false;
 
+      const cronFormat = this.item.cron_format;
+      const cronError = await this.validateCronFormat(cronFormat);
+
+      if (cronFormat !== this.item.cron_format) {
+        return; // the value changed while validating, ignore stale result
+      }
+
+      if (cronError != null) {
+        this.cronFormatError = cronError;
+        this.rawCron = true;
+        this.disableRawCron = true;
+        return;
+      }
+
       let cron;
       try {
         cron = CronExpressionParser.parse(this.item.cron_format, {
           tz: this.timezone,
         });
-      } catch (err) {
-        this.cronFormatError = getErrorMessage(err);
+      } catch {
+        // Valid on the backend but not parseable by cron-parser
+        // (e.g. @hourly) — show it in raw mode without an error.
         this.rawCron = true;
         this.disableRawCron = true;
         return;

++++++ semaphore.obsinfo ++++++
--- /var/tmp/diff_new_pack.0XE2VV/_old  2026-07-23 23:14:24.240834377 +0200
+++ /var/tmp/diff_new_pack.0XE2VV/_new  2026-07-23 23:14:24.252834799 +0200
@@ -1,5 +1,5 @@
 name: semaphore
-version: 2.18.26
-mtime: 1783856229
-commit: ee781a032ccb58c61de6b9a70993f9b6dc77dcf8
+version: 2.18.28
+mtime: 1784723083
+commit: 33874e063dd9d7dc441e11f7fbfc24c0c28b270f
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/semaphore/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.semaphore.new.2004/vendor.tar.gz differ: char 150, 
line 2

++++++ web-2.18.26.tar.gz -> web-2.18.28.tar.gz ++++++
/work/SRC/openSUSE:Factory/semaphore/web-2.18.26.tar.gz 
/work/SRC/openSUSE:Factory/.semaphore.new.2004/web-2.18.28.tar.gz differ: char 
31, line 1

Reply via email to