mirror of
https://github.com/mjl-/mox.git
synced 2025-04-21 21:40:01 +03:00
web interfaces: don't include version number in html, only return it after authentication
second round for issue #322
This commit is contained in:
parent
eeeabdc6de
commit
3a3a11560e
18 changed files with 217 additions and 35 deletions
|
@ -11,13 +11,11 @@ import (
|
|||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/mjl-/mox/mlog"
|
||||
"github.com/mjl-/mox/moxvar"
|
||||
)
|
||||
|
||||
// WebappFile serves a merged HTML and JS webapp as a single compressed, cacheable
|
||||
|
@ -182,7 +180,7 @@ func (a *WebappFile) Serve(ctx context.Context, log mlog.Log, w http.ResponseWri
|
|||
b.Write(html[cssi+len(cssp) : jsi])
|
||||
fmt.Fprintf(&b, "// Custom JS by admin from $configdir/%s.js:\n", a.CustomStem)
|
||||
b.Write(customJS)
|
||||
fmt.Fprintf(&b, "\n// Javascript is generated from typescript, don't modify the javascript because changes will be lost.\nconst moxversion = \"%s\";\nconst moxgoos = \"%s\";\nconst moxgoarch = \"%s\";\n", moxvar.Version, runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Fprintf(&b, "\n// Javascript is generated from typescript, don't modify the javascript because changes will be lost.\n")
|
||||
b.Write(js)
|
||||
b.Write(html[jsi+len(jsp):])
|
||||
out = b.Bytes()
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -368,6 +369,11 @@ func (w Account) Logout(ctx context.Context) {
|
|||
xcheckf(ctx, err, "logout")
|
||||
}
|
||||
|
||||
// Version returns the version, goos and goarch.
|
||||
func (Account) Version(ctx context.Context) (version, goos, goarch string) {
|
||||
return moxvar.Version, runtime.GOOS, runtime.GOARCH
|
||||
}
|
||||
|
||||
// SetPassword saves a new password for the account, invalidating the previous
|
||||
// password.
|
||||
//
|
||||
|
|
|
@ -380,6 +380,14 @@ var api;
|
|||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version() {
|
||||
const fn = "Version";
|
||||
const paramTypes = [];
|
||||
const returnTypes = [["string"], ["string"], ["string"]];
|
||||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// SetPassword saves a new password for the account, invalidating the previous
|
||||
// password.
|
||||
//
|
||||
|
@ -947,6 +955,9 @@ var api;
|
|||
};
|
||||
})(api || (api = {}));
|
||||
// Javascript is generated from typescript, do not modify generated javascript because changes will be overwritten.
|
||||
let moxversion;
|
||||
let moxgoos;
|
||||
let moxgoarch;
|
||||
const login = async (reason) => {
|
||||
return new Promise((resolve, _) => {
|
||||
const origFocus = document.activeElement;
|
||||
|
@ -1086,7 +1097,7 @@ const crumbs = (...l) => {
|
|||
];
|
||||
};
|
||||
const errmsg = (err) => '' + (err.message || '(no error message)');
|
||||
const footer = dom.div(style({ marginTop: '6ex', opacity: 0.75 }), link('https://www.xmox.nl', 'mox'), ' ', moxversion, ', ', dom.a(attr.href('licenses.txt'), 'licenses'));
|
||||
const footer = () => dom.div(style({ marginTop: '6ex', opacity: 0.75 }), link('https://www.xmox.nl', 'mox'), ' ', moxversion, ', ', dom.a(attr.href('licenses.txt'), 'licenses'));
|
||||
const domainName = (d) => {
|
||||
return d.Unicode || d.ASCII;
|
||||
};
|
||||
|
@ -1768,7 +1779,7 @@ openssl pkcs12 \\
|
|||
})), mailboxFileHint = dom.p(style({ display: 'none', fontStyle: 'italic', marginTop: '.5ex' }), 'This file must either be a zip file or a gzipped tar file with mbox and/or maildir mailboxes. For maildirs, an optional file "dovecot-keywords" is read additional keywords, like Forwarded/Junk/NotJunk. If an imported mailbox already exists by name, messages are added to the existing mailbox. If a mailbox does not yet exist it will be created. Messages are not deduplicated, importing them twice will result in duplicates.')), dom.div(style({ marginBottom: '1ex' }), dom.label(dom.div(style({ marginBottom: '.5ex' }), 'Skip mailbox prefix (optional)'), dom.input(attr.name('skipMailboxPrefix'), function focus() {
|
||||
mailboxPrefixHint.style.display = '';
|
||||
})), mailboxPrefixHint = dom.p(style({ display: 'none', fontStyle: 'italic', marginTop: '.5ex' }), 'If set, any mbox/maildir path with this prefix will have it stripped before importing. For example, if all mailboxes are in a directory "Takeout", specify that path in the field above so mailboxes like "Takeout/Inbox.mbox" are imported into a mailbox called "Inbox" instead of "Takeout/Inbox".')), dom.div(dom.submitbutton('Upload and import'), dom.p(style({ fontStyle: 'italic', marginTop: '.5ex' }), 'The file is uploaded first, then its messages are imported, finally messages are matched for threading. Importing is done in a transaction, you can abort the entire import before it is finished.')))), importAbortBox = dom.div(), // Outside fieldset because it gets disabled, above progress because may be scrolling it down quickly with problems.
|
||||
importProgress = dom.div(style({ display: 'none' })), dom.br(), footer);
|
||||
importProgress = dom.div(style({ display: 'none' })), dom.br(), footer());
|
||||
(async () => {
|
||||
// Try to show the progress of an earlier import session. The user may have just
|
||||
// refreshed the browser.
|
||||
|
@ -1926,6 +1937,7 @@ const destination = async (name) => {
|
|||
};
|
||||
const init = async () => {
|
||||
let curhash;
|
||||
[moxversion, moxgoos, moxgoarch] = await client.Version();
|
||||
const hashChange = async () => {
|
||||
if (curhash === window.location.hash) {
|
||||
return;
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
// From HTML.
|
||||
declare let page: HTMLElement
|
||||
declare let moxversion: string
|
||||
declare let moxgoos: string
|
||||
declare let moxgoarch: string
|
||||
// From customization script.
|
||||
declare let moxBeforeDisplay: (webmailroot: HTMLElement) => void
|
||||
|
||||
let moxversion: string
|
||||
let moxgoos: string
|
||||
let moxgoarch: string
|
||||
|
||||
const login = async (reason: string) => {
|
||||
return new Promise<string>((resolve: (v: string) => void, _) => {
|
||||
const origFocus = document.activeElement
|
||||
|
@ -206,13 +207,14 @@ const crumbs = (...l: ({text: string, path: string} | string)[]) => {
|
|||
|
||||
const errmsg = (err: unknown) => ''+((err as any).message || '(no error message)')
|
||||
|
||||
const footer = dom.div(
|
||||
style({marginTop: '6ex', opacity: 0.75}),
|
||||
link('https://www.xmox.nl', 'mox'),
|
||||
' ',
|
||||
moxversion,
|
||||
', ', dom.a(attr.href('licenses.txt'), 'licenses')
|
||||
)
|
||||
const footer = () =>
|
||||
dom.div(
|
||||
style({marginTop: '6ex', opacity: 0.75}),
|
||||
link('https://www.xmox.nl', 'mox'),
|
||||
' ',
|
||||
moxversion,
|
||||
', ', dom.a(attr.href('licenses.txt'), 'licenses')
|
||||
)
|
||||
|
||||
const domainName = (d: api.Domain) => {
|
||||
return d.Unicode || d.ASCII
|
||||
|
@ -1602,7 +1604,7 @@ openssl pkcs12 \\
|
|||
),
|
||||
dom.br(),
|
||||
|
||||
footer,
|
||||
footer(),
|
||||
)
|
||||
|
||||
;(async () => {
|
||||
|
@ -1944,6 +1946,8 @@ const destination = async (name: string) => {
|
|||
const init = async () => {
|
||||
let curhash: string | undefined
|
||||
|
||||
[moxversion, moxgoos, moxgoarch] = await client.Version()
|
||||
|
||||
const hashChange = async () => {
|
||||
if (curhash === window.location.hash) {
|
||||
return
|
||||
|
|
|
@ -53,6 +53,31 @@
|
|||
"Params": [],
|
||||
"Returns": []
|
||||
},
|
||||
{
|
||||
"Name": "Version",
|
||||
"Docs": "Version returns the version, goos and goarch.",
|
||||
"Params": [],
|
||||
"Returns": [
|
||||
{
|
||||
"Name": "version",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "goos",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "goarch",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "SetPassword",
|
||||
"Docs": "SetPassword saves a new password for the account, invalidating the previous\npassword.\n\nSessions are not interrupted, and will keep working. New login attempts must use\nthe new password.\n\nPassword must be at least 8 characters.\n\nSetting a user-supplied password is not allowed if NoCustomPassword is set\nfor the account.",
|
||||
|
|
|
@ -414,6 +414,15 @@ export class Client {
|
|||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
||||
}
|
||||
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version(): Promise<[string, string, string]> {
|
||||
const fn: string = "Version"
|
||||
const paramTypes: string[][] = []
|
||||
const returnTypes: string[][] = [["string"],["string"],["string"]]
|
||||
const params: any[] = []
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as [string, string, string]
|
||||
}
|
||||
|
||||
// SetPassword saves a new password for the account, invalidating the previous
|
||||
// password.
|
||||
//
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"sort"
|
||||
|
@ -279,6 +280,11 @@ func (w Admin) Logout(ctx context.Context) {
|
|||
xcheckf(ctx, err, "logout")
|
||||
}
|
||||
|
||||
// Version returns the version, goos and goarch.
|
||||
func (w Admin) Version(ctx context.Context) (version, goos, goarch string) {
|
||||
return moxvar.Version, runtime.GOOS, runtime.GOARCH
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
Errors []string
|
||||
Warnings []string
|
||||
|
|
|
@ -559,6 +559,14 @@ var api;
|
|||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version() {
|
||||
const fn = "Version";
|
||||
const paramTypes = [];
|
||||
const returnTypes = [["string"], ["string"], ["string"]];
|
||||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// CheckDomain checks the configuration for the domain, such as MX, SMTP STARTTLS,
|
||||
// SPF, DKIM, DMARC, TLSRPT, MTASTS, autoconfig, autodiscover.
|
||||
async CheckDomain(domainName) {
|
||||
|
@ -1694,6 +1702,9 @@ var api;
|
|||
};
|
||||
})(api || (api = {}));
|
||||
// Javascript is generated from typescript, do not modify generated javascript because changes will be overwritten.
|
||||
let moxversion;
|
||||
let moxgoos;
|
||||
let moxgoarch;
|
||||
const login = async (reason) => {
|
||||
return new Promise((resolve, _) => {
|
||||
const origFocus = document.activeElement;
|
||||
|
@ -1833,7 +1844,7 @@ const crumbs = (...l) => {
|
|||
];
|
||||
};
|
||||
const errmsg = (err) => '' + (err.message || '(no error message)');
|
||||
const footer = dom.div(style({ marginTop: '6ex', opacity: 0.75 }), link('https://www.xmox.nl', 'mox'), ' ', moxversion, ' ', moxgoos, '/', moxgoarch, ', ', dom.a(attr.href('licenses.txt'), 'licenses'));
|
||||
const footer = () => dom.div(style({ marginTop: '6ex', opacity: 0.75 }), link('https://www.xmox.nl', 'mox'), ' ', moxversion, ' ', moxgoos, '/', moxgoarch, ', ', dom.a(attr.href('licenses.txt'), 'licenses'));
|
||||
const age = (date, future, nowSecs) => {
|
||||
if (!nowSecs) {
|
||||
nowSecs = new Date().getTime() / 1000;
|
||||
|
@ -1987,7 +1998,7 @@ const index = async () => {
|
|||
dom._kids(cidElem, cid);
|
||||
}, recvIDFieldset = dom.fieldset(dom.label('Received ID', attr.title('The ID in the Received header that was added during incoming delivery.')), ' ', recvID = dom.input(attr.required('')), ' ', dom.submitbutton('Lookup cid', attr.title('Logging about an incoming message includes an attribute "cid", a counter identifying the transaction related to delivery of the message. The ID in the received header is an encrypted cid, which this form decrypts, after which you can look it up in the logging.')), ' ', cidElem = dom.span()))),
|
||||
// todo: routing, globally, per domain and per account
|
||||
dom.br(), dom.h2('Configuration'), dom.div(dom.a('Routes', attr.href('#routes'))), dom.div(dom.a('Webserver', attr.href('#webserver'))), dom.div(dom.a('Files', attr.href('#config'))), dom.div(dom.a('Log levels', attr.href('#loglevels'))), footer);
|
||||
dom.br(), dom.h2('Configuration'), dom.div(dom.a('Routes', attr.href('#routes'))), dom.div(dom.a('Webserver', attr.href('#webserver'))), dom.div(dom.a('Files', attr.href('#config'))), dom.div(dom.a('Log levels', attr.href('#loglevels'))), footer());
|
||||
};
|
||||
const globalRoutes = async () => {
|
||||
const [transports, config] = await Promise.all([
|
||||
|
@ -4149,6 +4160,7 @@ const webserver = async () => {
|
|||
};
|
||||
const init = async () => {
|
||||
let curhash;
|
||||
[moxversion, moxgoos, moxgoarch] = await client.Version();
|
||||
const hashChange = async () => {
|
||||
if (curhash === window.location.hash) {
|
||||
return;
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
// From HTML.
|
||||
declare let page: HTMLElement
|
||||
declare let moxversion: string
|
||||
declare let moxgoos: string
|
||||
declare let moxgoarch: string
|
||||
// From customization script.
|
||||
declare let moxBeforeDisplay: (webmailroot: HTMLElement) => void
|
||||
|
||||
let moxversion: string
|
||||
let moxgoos: string
|
||||
let moxgoarch: string
|
||||
|
||||
const login = async (reason: string) => {
|
||||
return new Promise<string>((resolve: (v: string) => void, _) => {
|
||||
const origFocus = document.activeElement
|
||||
|
@ -191,14 +192,15 @@ const crumbs = (...l: ({text: string, path: string} | string)[]) => {
|
|||
|
||||
const errmsg = (err: unknown) => ''+((err as any).message || '(no error message)')
|
||||
|
||||
const footer = dom.div(
|
||||
style({marginTop: '6ex', opacity: 0.75}),
|
||||
link('https://www.xmox.nl', 'mox'),
|
||||
' ',
|
||||
moxversion, ' ',
|
||||
moxgoos, '/', moxgoarch,
|
||||
', ', dom.a(attr.href('licenses.txt'), 'licenses')
|
||||
)
|
||||
const footer = () =>
|
||||
dom.div(
|
||||
style({marginTop: '6ex', opacity: 0.75}),
|
||||
link('https://www.xmox.nl', 'mox'),
|
||||
' ',
|
||||
moxversion, ' ',
|
||||
moxgoos, '/', moxgoarch,
|
||||
', ', dom.a(attr.href('licenses.txt'), 'licenses')
|
||||
)
|
||||
|
||||
const age = (date: Date, future: boolean, nowSecs: number) => {
|
||||
if (!nowSecs) {
|
||||
|
@ -438,7 +440,7 @@ const index = async () => {
|
|||
dom.div(dom.a('Webserver', attr.href('#webserver'))),
|
||||
dom.div(dom.a('Files', attr.href('#config'))),
|
||||
dom.div(dom.a('Log levels', attr.href('#loglevels'))),
|
||||
footer,
|
||||
footer(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -4249,7 +4251,7 @@ const hooksList = async () => {
|
|||
style({textAlign: 'right'}), // Less content shifting while rendering.
|
||||
'Sort ',
|
||||
sortElem=dom.select(
|
||||
attr.form('hooksfilter'),
|
||||
attr.form('hooksfilter'),
|
||||
function change() {
|
||||
filterForm.requestSubmit()
|
||||
},
|
||||
|
@ -5342,6 +5344,8 @@ const webserver = async () => {
|
|||
const init = async () => {
|
||||
let curhash: string | undefined
|
||||
|
||||
[moxversion, moxgoos, moxgoarch] = await client.Version()
|
||||
|
||||
const hashChange = async () => {
|
||||
if (curhash === window.location.hash) {
|
||||
return
|
||||
|
|
|
@ -47,6 +47,31 @@
|
|||
"Params": [],
|
||||
"Returns": []
|
||||
},
|
||||
{
|
||||
"Name": "Version",
|
||||
"Docs": "Version returns the version, goos and goarch.",
|
||||
"Params": [],
|
||||
"Returns": [
|
||||
{
|
||||
"Name": "version",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "goos",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "goarch",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "CheckDomain",
|
||||
"Docs": "CheckDomain checks the configuration for the domain, such as MX, SMTP STARTTLS,\nSPF, DKIM, DMARC, TLSRPT, MTASTS, autoconfig, autodiscover.",
|
||||
|
|
|
@ -1457,6 +1457,15 @@ export class Client {
|
|||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
||||
}
|
||||
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version(): Promise<[string, string, string]> {
|
||||
const fn: string = "Version"
|
||||
const paramTypes: string[][] = []
|
||||
const returnTypes: string[][] = [["string"],["string"],["string"]]
|
||||
const params: any[] = []
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as [string, string, string]
|
||||
}
|
||||
|
||||
// CheckDomain checks the configuration for the domain, such as MX, SMTP STARTTLS,
|
||||
// SPF, DKIM, DMARC, TLSRPT, MTASTS, autoconfig, autodiscover.
|
||||
async CheckDomain(domainName: string): Promise<CheckResult> {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"net/textproto"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"sort"
|
||||
|
@ -130,6 +131,11 @@ func (w Webmail) Logout(ctx context.Context) {
|
|||
xcheckf(ctx, err, "logout")
|
||||
}
|
||||
|
||||
// Version returns the version, goos and goarch.
|
||||
func (w Webmail) Version(ctx context.Context) (version, goos, goarch string) {
|
||||
return moxvar.Version, runtime.GOOS, runtime.GOARCH
|
||||
}
|
||||
|
||||
// Token returns a single-use token to use for an SSE connection. A token can only
|
||||
// be used for a single SSE connection. Tokens are stored in memory for a maximum
|
||||
// of 1 minute, with at most 10 unused tokens (the most recently created) per
|
||||
|
|
|
@ -53,6 +53,31 @@
|
|||
"Params": [],
|
||||
"Returns": []
|
||||
},
|
||||
{
|
||||
"Name": "Version",
|
||||
"Docs": "Version returns the version, goos and goarch.",
|
||||
"Params": [],
|
||||
"Returns": [
|
||||
{
|
||||
"Name": "version",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "goos",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "goarch",
|
||||
"Typewords": [
|
||||
"string"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "Token",
|
||||
"Docs": "Token returns a single-use token to use for an SSE connection. A token can only\nbe used for a single SSE connection. Tokens are stored in memory for a maximum\nof 1 minute, with at most 10 unused tokens (the most recently created) per\naccount.",
|
||||
|
|
|
@ -765,6 +765,15 @@ export class Client {
|
|||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
||||
}
|
||||
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version(): Promise<[string, string, string]> {
|
||||
const fn: string = "Version"
|
||||
const paramTypes: string[][] = []
|
||||
const returnTypes: string[][] = [["string"],["string"],["string"]]
|
||||
const params: any[] = []
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as [string, string, string]
|
||||
}
|
||||
|
||||
// Token returns a single-use token to use for an SSE connection. A token can only
|
||||
// be used for a single SSE connection. Tokens are stored in memory for a maximum
|
||||
// of 1 minute, with at most 10 unused tokens (the most recently created) per
|
||||
|
|
|
@ -448,6 +448,14 @@ var api;
|
|||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version() {
|
||||
const fn = "Version";
|
||||
const paramTypes = [];
|
||||
const returnTypes = [["string"], ["string"], ["string"]];
|
||||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Token returns a single-use token to use for an SSE connection. A token can only
|
||||
// be used for a single SSE connection. Tokens are stored in memory for a maximum
|
||||
// of 1 minute, with at most 10 unused tokens (the most recently created) per
|
||||
|
|
|
@ -448,6 +448,14 @@ var api;
|
|||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version() {
|
||||
const fn = "Version";
|
||||
const paramTypes = [];
|
||||
const returnTypes = [["string"], ["string"], ["string"]];
|
||||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Token returns a single-use token to use for an SSE connection. A token can only
|
||||
// be used for a single SSE connection. Tokens are stored in memory for a maximum
|
||||
// of 1 minute, with at most 10 unused tokens (the most recently created) per
|
||||
|
|
|
@ -448,6 +448,14 @@ var api;
|
|||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Version returns the version, goos and goarch.
|
||||
async Version() {
|
||||
const fn = "Version";
|
||||
const paramTypes = [];
|
||||
const returnTypes = [["string"], ["string"], ["string"]];
|
||||
const params = [];
|
||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||
}
|
||||
// Token returns a single-use token to use for an SSE connection. A token can only
|
||||
// be used for a single SSE connection. Tokens are stored in memory for a maximum
|
||||
// of 1 minute, with at most 10 unused tokens (the most recently created) per
|
||||
|
@ -1571,6 +1579,9 @@ const yscrollAutoStyle = css('yscrollAuto', { overflowY: 'auto', position: 'abso
|
|||
const autosizeStyle = css('autosize', { display: 'inline-grid', maxWidth: '90vw' });
|
||||
ensureCSS('.autosize.input', { gridArea: '1 / 2' });
|
||||
ensureCSS('.autosize::after', { content: 'attr(data-value)', marginRight: '1em', lineHeight: 0, visibility: 'hidden', whiteSpace: 'pre-wrap', overflowX: 'hidden' });
|
||||
let moxversion;
|
||||
let moxgoos;
|
||||
let moxgoarch;
|
||||
// All logging goes through log() instead of console.log, except "should not happen" logging.
|
||||
let log = () => { };
|
||||
try {
|
||||
|
@ -6329,7 +6340,9 @@ const init = async () => {
|
|||
let requestViewEnd = false; // If true, there is no more data to fetch, no more page needed for this view.
|
||||
let requestFilter = newFilter();
|
||||
let requestNotFilter = newNotFilter();
|
||||
let requestMsgID = 0; // If > 0, we are still expecting a parsed message for the view, coming from the query. Either we get it and set msgitemViewActive and clear this, or we get to the end of the data and clear it.
|
||||
let requestMsgID = 0 // If > 0, we are still expecting a parsed message for the view, coming from the query. Either we get it and set msgitemViewActive and clear this, or we get to the end of the data and clear it.
|
||||
;
|
||||
[moxversion, moxgoos, moxgoarch] = await client.Version();
|
||||
const updatePageTitle = () => {
|
||||
const mb = mailboxlistView && mailboxlistView.activeMailbox();
|
||||
const addr = loginAddress ? loginAddress.User + '@' + formatDomain(loginAddress.Domain) : '';
|
||||
|
|
|
@ -127,12 +127,13 @@ ensureCSS('.autosize::after', {content: 'attr(data-value)', marginRight: '1em',
|
|||
|
||||
// From HTML.
|
||||
declare let page: HTMLElement
|
||||
declare let moxversion: string
|
||||
declare let moxgoos: string
|
||||
declare let moxgoarch: string
|
||||
// From customization script.
|
||||
declare let moxBeforeDisplay: (root: HTMLElement) => void
|
||||
|
||||
let moxversion: string
|
||||
let moxgoos: string
|
||||
let moxgoarch: string
|
||||
|
||||
// All logging goes through log() instead of console.log, except "should not happen" logging.
|
||||
let log: (...args: any[]) => void = () => {}
|
||||
try {
|
||||
|
@ -6342,6 +6343,8 @@ const init = async () => {
|
|||
let requestNotFilter = newNotFilter()
|
||||
let requestMsgID = 0 // If > 0, we are still expecting a parsed message for the view, coming from the query. Either we get it and set msgitemViewActive and clear this, or we get to the end of the data and clear it.
|
||||
|
||||
;[moxversion, moxgoos, moxgoarch] = await client.Version()
|
||||
|
||||
const updatePageTitle = () => {
|
||||
const mb = mailboxlistView && mailboxlistView.activeMailbox()
|
||||
const addr = loginAddress ? loginAddress.User+'@'+formatDomain(loginAddress.Domain) : ''
|
||||
|
|
Loading…
Reference in a new issue