diff --git a/data/web/js/build/013-mailcow.js b/data/web/js/build/013-mailcow.js
index a5420e73e..ac8b5258f 100644
--- a/data/web/js/build/013-mailcow.js
+++ b/data/web/js/build/013-mailcow.js
@@ -428,6 +428,32 @@ function imapsyncScopeDisplay(item) {
return escapeHtml(lang.syncjobs.source_scope_user + ': ' + us.join(', '));
}
+// Auth column for a source row: auth type, and for XOAUTH2 the flow + a token-status badge.
+function imapsyncAuthDisplay(item) {
+ var out = escapeHtml(item.auth_type);
+ if (item.auth_type !== 'XOAUTH2') return out;
+ var flow = item.oauth_flow || 'client_credentials';
+ var flowLabel = (flow === 'authorization_code')
+ ? lang.syncjobs.source_flow_badge_user
+ : lang.syncjobs.source_flow_badge_app;
+ out += ' (' + escapeHtml(flowLabel) + ')';
+ if (flow === 'authorization_code') {
+ // token lives per user+source (created via the syncjob "connect"), not on the source row
+ return out;
+ }
+ var badge;
+ if (item.oauth_token_expires && item.oauth_token_expires * 1000 > Date.now()) {
+ badge = '' + lang.syncjobs.source_token_status + ': ' + new Date(item.oauth_token_expires * 1000).toLocaleString() + '';
+ } else if (item.oauth_last_refresh_error) {
+ badge = '' + lang.syncjobs.source_token_error + '';
+ } else {
+ badge = '' + lang.waiting + '';
+ }
+ // badge on its own line, below "XOAUTH2 (Client Credentials)"
+ out += '
' +
diff --git a/data/web/js/site/user.js b/data/web/js/site/user.js
index 77064f8ec..ceee0a377 100644
--- a/data/web/js/site/user.js
+++ b/data/web/js/site/user.js
@@ -721,16 +721,7 @@ jQuery(function($){
dataSrc: function(json) {
$.each(json, function(i, item) {
item.endpoint = escapeHtml(item.host1 + ':' + item.port1 + ' (' + item.enc1 + ')');
- item.auth_display = escapeHtml(item.auth_type);
- if (item.auth_type === 'XOAUTH2') {
- if (item.oauth_token_expires && item.oauth_token_expires * 1000 > Date.now()) {
- item.auth_display += '
' + lang.syncjobs.source_token_status + ': ' + new Date(item.oauth_token_expires * 1000).toLocaleString() + '';
- } else if (item.oauth_last_refresh_error) {
- item.auth_display += '
' + lang.syncjobs.source_token_error + '';
- } else {
- item.auth_display += '
' + lang.waiting + '';
- }
- }
+ item.auth_display = imapsyncAuthDisplay(item);
item.visibility_display = imapsyncScopeDisplay(item);
if (acl_data.syncjobs === 1 && item.can_edit) {
item.action = '
' +
diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json
index 01385c572..1956de59e 100644
--- a/data/web/lang/lang.de-de.json
+++ b/data/web/lang/lang.de-de.json
@@ -1256,6 +1256,8 @@
"source_oauth_flow": "OAuth2-Flow",
"source_oauth_flow_app": "App (Client Credentials)",
"source_oauth_flow_user": "Benutzer-Login (Authorization Code)",
+ "source_flow_badge_app": "Client Credentials",
+ "source_flow_badge_user": "Benutzer-Login",
"source_authorize_endpoint": "Authorize-Endpoint",
"source_userinfo_endpoint": "Userinfo-Endpoint",
"source_redirect_uri": "Redirect-URI",
diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json
index 33b8f9ae2..c1822c39e 100644
--- a/data/web/lang/lang.en-gb.json
+++ b/data/web/lang/lang.en-gb.json
@@ -1263,6 +1263,8 @@
"source_oauth_flow": "OAuth2 flow",
"source_oauth_flow_app": "App (client credentials)",
"source_oauth_flow_user": "User login (authorization code)",
+ "source_flow_badge_app": "Client credentials",
+ "source_flow_badge_user": "User login",
"source_authorize_endpoint": "Authorize endpoint",
"source_userinfo_endpoint": "Userinfo endpoint",
"source_redirect_uri": "Redirect URI",