Choose how IRC proves who you are
A mechanism picker in the SASL block, defaulted rather than chosen: the default is right for nearly everyone, and each alternative needs something the network has to support first. The certificate field appears only for EXTERNAL, since every other mechanism ignores it and a path box beside PLAIN reads as something that does nothing. The path is never reported back - a frontend has no use for it, and it names a file on whichever machine the daemon runs on rather than this one - so the field shows only whether one is set. SCRAM says plainly that almost no IRC network offers it. Better than letting somebody pick it, watch the connection fail, and conclude the client is broken. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+1
-1
Submodule nobilis updated: 696b08a76e...2f37c476eb
@@ -361,7 +361,13 @@ function IrcSasl({
|
||||
const [password, setPassword] = useState('')
|
||||
const [allowPlaintext, setAllowPlaintext] = useState(account.allowPlaintextSasl)
|
||||
|
||||
const apply = (patch: { enabled?: boolean; saslUser?: string; allowPlaintextSasl?: boolean }): void =>
|
||||
const apply = (patch: {
|
||||
enabled?: boolean
|
||||
saslUser?: string
|
||||
allowPlaintextSasl?: boolean
|
||||
saslMechanism?: string
|
||||
saslCertPath?: string
|
||||
}): void =>
|
||||
call('setAccountSasl', {
|
||||
accountId: account.id,
|
||||
enabled: account.saslEnabled,
|
||||
@@ -418,6 +424,46 @@ function IrcSasl({
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* How the password is proved, where it is proved at all.
|
||||
Defaulted rather than chosen, because the default is right for
|
||||
nearly everyone and the alternatives each need something the
|
||||
network has to support first. */}
|
||||
<label className="field">
|
||||
<span className="small muted">Mechanism</span>
|
||||
<select
|
||||
className="text-field"
|
||||
value={account.saslMechanism}
|
||||
onChange={(e) => apply({ saslMechanism: e.target.value })}
|
||||
>
|
||||
<option value="">Automatic — a certificate if set, otherwise PLAIN</option>
|
||||
<option value="plain">PLAIN — the password, inside TLS</option>
|
||||
<option value="scram-sha-256">SCRAM-SHA-256 — proves the password without sending it</option>
|
||||
<option value="external">EXTERNAL — the client certificate, no password at all</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
{/* Only where the mechanism needs one. EXTERNAL is the certificate;
|
||||
everything else ignores it, and a path field beside PLAIN would
|
||||
read as something that does nothing. */}
|
||||
{(account.saslMechanism === 'external' || account.hasSaslCertificate) && (
|
||||
<LabeledInput
|
||||
label="Client certificate"
|
||||
defaultValue={account.hasSaslCertificate ? '(set)' : ''}
|
||||
placeholder="/path/to/cert.pem on the daemon's machine"
|
||||
onCommit={(value) => apply({ saslCertPath: value === '(set)' ? undefined : value })}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* SCRAM proves the password to the server without sending it, and
|
||||
proves the server knew it too - worth saying, because that second
|
||||
half is the part people do not expect from a login. */}
|
||||
{account.saslMechanism === 'scram-sha-256' && (
|
||||
<p className="small muted">
|
||||
Few IRC networks offer SCRAM — Ergo does, Libera and Rizon do not. If this server
|
||||
refuses it and says what it does accept, moho falls back to that automatically.
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* Only where it is a live question. On a TLS connection the
|
||||
allowance decides nothing, and offering it there would be a
|
||||
switch that appears to weaken something and does not. */}
|
||||
|
||||
@@ -16,6 +16,16 @@ export interface Account {
|
||||
saslEnabled: boolean
|
||||
saslUsername: string
|
||||
allowPlaintextSasl: boolean
|
||||
/** Which SASL mechanism this account is pinned to, or '' for the default. */
|
||||
saslMechanism: string
|
||||
/**
|
||||
* Whether a TLS client certificate is configured for SASL EXTERNAL.
|
||||
*
|
||||
* The path itself is deliberately not reported: a frontend never needs it,
|
||||
* and it names a file on whichever machine the daemon runs on rather than
|
||||
* this one.
|
||||
*/
|
||||
hasSaslCertificate: boolean
|
||||
/**
|
||||
* Whether the connection is encrypted. Only IRC is ever false - every other
|
||||
* service here is HTTPS or WSS by construction.
|
||||
|
||||
Reference in New Issue
Block a user