Give identity its due: native enrollment, honest deletion, and sign-in that stays home
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -25,6 +25,12 @@ Singleton {
|
||||
property bool scanned: false
|
||||
property string lastError: ""
|
||||
|
||||
// The pictures the distribution ships, as [{name, path}]. Read once and
|
||||
// kept: it is a directory listing that does not change while a session is
|
||||
// running, and the gallery it fills is opened and closed repeatedly.
|
||||
property var stockAvatars: []
|
||||
property bool stockAvatarsLoaded: false
|
||||
|
||||
// Guards read the Process objects rather than a derived "busy" binding. A
|
||||
// binding hands back its cached value inside the handler that changes it,
|
||||
// which silently turns a refresh after a successful change into a no-op --
|
||||
@@ -115,7 +121,27 @@ Singleton {
|
||||
String(Math.round(x)), String(Math.round(y)), String(Math.round(size))]);
|
||||
}
|
||||
|
||||
function setAccountType(userName: string, kind: string): void {
|
||||
// Clearing the picture is the same call with nothing in it -- there is no
|
||||
// separate method for it in accountsservice, and there is none here either.
|
||||
// No user name: this is the hero card's own avatar, and an account you are
|
||||
// not signed in to has no avatar surface to remove it from.
|
||||
function removeIcon(): void {
|
||||
root.settingIcon = true;
|
||||
root.run(["set-icon", root.currentUser, ""]);
|
||||
}
|
||||
|
||||
// Called when the gallery is about to be shown, not at startup: most
|
||||
// sessions never open it, and it is a directory listing either way.
|
||||
function loadStockAvatars(): void {
|
||||
if (root.stockAvatarsLoaded || stock.running)
|
||||
return;
|
||||
stock.running = true;
|
||||
}
|
||||
|
||||
// Any account, including one that is not signed in. The helper keeps the
|
||||
// last-administrator refusal, so a page that forgets the guard still
|
||||
// cannot leave the machine unadministrable.
|
||||
function setAccountTypeFor(userName: string, kind: string): void {
|
||||
root.run(["set-account-type", userName, kind]);
|
||||
}
|
||||
|
||||
@@ -123,12 +149,28 @@ Singleton {
|
||||
root.run(["set-automatic-login", userName, enabled ? "true" : "false"]);
|
||||
}
|
||||
|
||||
// Locked accounts cannot sign in at all. Unlocking is the only half of this
|
||||
// the page offers, because locking someone out is not a settings gesture.
|
||||
function setLocked(userName: string, locked: bool): void {
|
||||
root.run(["set-locked", userName, locked ? "true" : "false"]);
|
||||
}
|
||||
|
||||
// No password of any kind is involved: accountsservice is told the account
|
||||
// must choose one at the next sign-in, and the login screen collects it
|
||||
// from the person who will use it.
|
||||
function resetPassword(userName: string): void {
|
||||
root.run(["reset-password", userName]);
|
||||
}
|
||||
|
||||
function createUser(userName: string, realName: string, kind: string): void {
|
||||
root.run(["create-user", userName, realName, kind]);
|
||||
}
|
||||
|
||||
function deleteUser(userName: string, removeFiles: bool): void {
|
||||
root.run(["delete-user", userName, removeFiles ? "remove-files" : "keep-files"]);
|
||||
// keepFiles, not removeFiles: the page asks "Keep the files" or "Remove
|
||||
// everything", and a service that inverted the sentence on its way to the
|
||||
// helper is how the destructive answer gets chosen by accident.
|
||||
function deleteUser(userName: string, keepFiles: bool): void {
|
||||
root.run(["delete-user", userName, keepFiles ? "keep" : "remove"]);
|
||||
}
|
||||
|
||||
// The password goes to the helper's stdin and nowhere else: never an
|
||||
@@ -177,6 +219,25 @@ Singleton {
|
||||
onExited: root.pendingPassword = ""
|
||||
}
|
||||
|
||||
Process {
|
||||
id: stock
|
||||
command: [root.helperPath, "stock-avatars"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
try {
|
||||
const parsed = JSON.parse(this.text);
|
||||
root.stockAvatars = Array.isArray(parsed.avatars) ? parsed.avatars : [];
|
||||
} catch (error) {
|
||||
// A machine with no gallery is normal; an empty one reads
|
||||
// the same to the page, and nothing else here depends on it.
|
||||
root.stockAvatars = [];
|
||||
console.warn("Accounts: could not read the stock avatars:", error);
|
||||
}
|
||||
root.stockAvatarsLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: mutation
|
||||
// The helper answers with the fresh state, so the page updates from the
|
||||
|
||||
Reference in New Issue
Block a user