Signals: an admin chooses whether the server's TypeSafe key pays for everyone (#271)
With signals_on_server set and TYPESAFE_KEY present, the judge asks Jev about everyone's Signals on the server's key; otherwise each person turns Signals on in Settings with a key of their own, which is now checked with TypeSafe before it is saved. The Signals folder shows only when they are on. The browser suite's daemon inherited the shell's TYPESAFE_KEY, so fixture feeds were sent to the real TypeSafe to be categorised; it is blanked now, and an empty key counts as none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -440,13 +440,18 @@ async function prefsModal(){
|
||||
<span class="hint">Comma separated words or phrases, in every feed you read. An item with
|
||||
one in its title or text is hidden from you and not downloaded for you. Each feed's
|
||||
settings can add more.</span></div>
|
||||
<div class="field"><label for="stskey">TypeSafe key</label>
|
||||
<div class="inline"><input type="password" id="stskey" autocomplete="off" spellcheck="false"
|
||||
placeholder="${S.me?.typesafe_key_set?'Saved. Paste a new one to replace it':'Paste your key'}">
|
||||
<button class="btn ico" id="stsforget" title="Forget the key" aria-label="Forget the key"${S.me?.typesafe_key_set?'':' hidden'}>${ICON.trash}</button></div>
|
||||
<span class="hint">Signals pick what matters out of everything you subscribe to, on your own
|
||||
key from <a href="https://typesafe.ai" target="_blank" rel="noopener">typesafe.ai</a>.
|
||||
The key is kept on this server and never shown again.</span></div>
|
||||
${S.me?.signals==='server'?`<div class="field"><label>Signals</label>
|
||||
<span class="hint">Signals pick what matters out of everything you subscribe to. This server
|
||||
pays for them, so there is nothing to set up.</span></div>`:`<div class="field">
|
||||
<label class="check"><input type="checkbox" id="ssigon"${S.me?.typesafe_key_set?' checked':''}> Signals</label>
|
||||
<span class="hint">Signals pick what matters out of everything you subscribe to. To use Signals
|
||||
you will need an API key from <a href="https://typesafe.ai" target="_blank" rel="noopener">typesafe.ai</a>.</span>
|
||||
<div id="ssigkey"${S.me?.typesafe_key_set?'':' hidden'}>
|
||||
<label for="stskey">TypeSafe key</label>
|
||||
<div class="inline"><input type="password" id="stskey" autocomplete="off" spellcheck="false"
|
||||
placeholder="${S.me?.typesafe_key_set?'Saved. Paste a new one to replace it':'Paste your key'}">
|
||||
<button class="btn ico" id="stsforget" title="Forget the key" aria-label="Forget the key"${S.me?.typesafe_key_set?'':' hidden'}>${ICON.trash}</button></div>
|
||||
<span class="hint">Checked with TypeSafe before it is saved, kept on this server and never shown again.</span></div></div>`}
|
||||
<div class="field boxed"><label for="tokname">API tokens</label>
|
||||
<div id="tokens"></div>
|
||||
<div class="inline"><input type="text" id="tokname" placeholder="What it is for">
|
||||
@@ -476,18 +481,31 @@ async function prefsModal(){
|
||||
$<HTMLInputElement>('#tokval').select();
|
||||
}catch(err){ toast(why(err),true); }
|
||||
};
|
||||
const saveKey=async(typesafe_key: string|null)=>{
|
||||
try{
|
||||
await api('/api/me',{method:'PATCH',body:JSON.stringify({typesafe_key})});
|
||||
if(S.me) S.me.typesafe_key_set=!!typesafe_key;
|
||||
$<HTMLInputElement>('#stskey').value='';
|
||||
$<HTMLInputElement>('#stskey').placeholder=typesafe_key?'Saved. Paste a new one to replace it':'Paste your key';
|
||||
$<HTMLButtonElement>('#stsforget').hidden=!typesafe_key;
|
||||
toast(typesafe_key?'Saved':'Forgotten');
|
||||
}catch(err){ toast(why(err),true); }
|
||||
};
|
||||
$<HTMLInputElement>('#stskey').onchange=(e: Event)=>{ const k=(e.target as HTMLInputElement).value.trim(); if(k) saveKey(k); };
|
||||
$<HTMLButtonElement>('#stsforget').onclick=()=>saveKey(null);
|
||||
// Your own key, unless the server's is used for everyone (#271). Signals are on once TypeSafe
|
||||
// has taken a key, and off again when it is forgotten.
|
||||
if(S.me?.signals!=='server'){
|
||||
const saveKey=async(typesafe_key: string|null)=>{
|
||||
try{
|
||||
await api('/api/me',{method:'PATCH',body:JSON.stringify({typesafe_key})});
|
||||
if(S.me) S.me.typesafe_key_set=!!typesafe_key;
|
||||
$<HTMLInputElement>('#stskey').value='';
|
||||
$<HTMLInputElement>('#stskey').placeholder=typesafe_key?'Saved. Paste a new one to replace it':'Paste your key';
|
||||
$<HTMLButtonElement>('#stsforget').hidden=!typesafe_key;
|
||||
$<HTMLInputElement>('#ssigon').checked=!!typesafe_key; $('#ssigkey').hidden=!typesafe_key;
|
||||
toast(typesafe_key?'Signals are on':'Signals are off');
|
||||
renderFeeds();
|
||||
}catch(err){ toast(why(err),true); }
|
||||
};
|
||||
$<HTMLInputElement>('#ssigon').onchange=(e: Event)=>{
|
||||
const on=(e.target as HTMLInputElement).checked;
|
||||
if(on){ $('#ssigkey').hidden=false; $<HTMLInputElement>('#stskey').focus(); return; }
|
||||
if(!S.me?.typesafe_key_set){ $('#ssigkey').hidden=true; return; }
|
||||
if(confirm('Turn Signals off and forget your TypeSafe key? Your signals are kept for when you turn them on again.')) saveKey(null);
|
||||
else (e.target as HTMLInputElement).checked=true;
|
||||
};
|
||||
$<HTMLInputElement>('#stskey').onchange=(e: Event)=>{ const k=(e.target as HTMLInputElement).value.trim(); if(k) saveKey(k); };
|
||||
$<HTMLButtonElement>('#stsforget').onclick=()=>$<HTMLInputElement>('#ssigon').click();
|
||||
}
|
||||
$<HTMLInputElement>('#sblock').onchange=async (e: Event)=>{
|
||||
const blocked=splitWords((e.target as HTMLInputElement).value);
|
||||
try{
|
||||
|
||||
Reference in New Issue
Block a user