--- title: "1.40.0 — Microsoft sign-in, one file manager per purpose" description: "Microsoft (Entra ID) joins the OAuth providers, off by default. A group or user now has exactly one active file manager per purpose, and global Assistant memory writes need `view_admin`. Group rows are locked in a mode that no longer collides with the tenant's own inserts." date: "2026-10-28" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-40-0/" --- Microsoft (Entra ID) joins the OAuth providers, off by default. A group or user now has exactly one active file manager per purpose, and global Assistant memory writes need `view_admin`. Group rows are locked in a mode that no longer collides with the tenant's own inserts. ### Breaking - Creating a second active file manager for the same owner (group or user) and purpose is refused with 400. Existing duplicates keep working and can be edited in place; auto-create returns the manager that already holds the purpose. The read-only `fileman_duplicate_uses` command lists pre-existing duplicates and the one each scope now selects. - Creating, overwriting or deleting global Assistant memory requires `view_admin` or superuser, through REST, Assistant tools, MCP and approved cards alike. An approved card re-checks the live user. The first-run memory prompt is shown only to users who can write global memory. ### Added - Microsoft sign-in as an OAuth provider: PKCE, fully validated ID tokens, tenant policy, a Sign-in card with client-secret expiry notices, hosted login and register buttons, and `startMicrosoftLogin`. Off until a site adds it to its login and registration methods. - Login and registration method defaults are explicit lists, so a provider added later stays off until switched on and no site shows a button that cannot work. - An opt-in provider that is switched off system-wide is refused at begin, with or without a group context. - The S3 storage backend accepts `session_factory` and `assumed_session_factory` keywords; a backend built with either keeps its clients out of the shared client cache. Unused, behaviour is unchanged. ### Changed - File manager lookups by owner and purpose pick the default manager first, then the oldest, so the same manager is always chosen; `is_default` is per purpose. - Group rows are locked `FOR NO KEY UPDATE` on PostgreSQL (account app and dnsman). Other writers are still excluded; the tenant's child-row inserts and commits no longer wait on a group save, nor it on them. Code that locks a Group row itself should use `group_hierarchy.lock_rows`. - A Microsoft login links to an existing account by email only when Microsoft reports the address verified; an unverified match is refused, and a profile without a verified email creates the account with no email address. The docs now say OAuth logins are not subject to `REQUIRE_VERIFIED_EMAIL`. - Vendored portal-mojo Admin 0.2.22: Microsoft labels, Sign-in notices, operations pages, protected browser delivery. - Admin clone: a node whose disk has no deployment profile marker is quarantined on first boot, with the app, config sync and job engine held off and the cron moved aside, then powered off. The add operation reports `clone_refused` with the recovery steps. Stage 1 writes the marker before the deploy script runs. - testit: the agent report gains a budget block, and a blown core wall-clock budget now reports `failed` instead of `passed`. django-mojo's own framework budget is 210 s, measured; the consumer default stays 90 s. ### Fixed - JSON-field values loaded as objict, and other dict subclasses, serialized as null in graphs and CSV exports. - The Assistant's user detail and permission summary readers raised an import error on every call. - Job workers keep their delivery receipt across transient database failures, and the reaper removes only receipts still stale at its cutoff, so a renewed worker is not reaped. - Two S3 backends for one manager and endpoint with different injected clients no longer share the first one's client. ### Upgrade notes - If several active file managers share a purpose for one owner, run `fileman_duplicate_uses` first: nothing is changed on upgrade, but lookups now pick a fixed one. - Clients that create global Assistant memory need `view_admin` after upgrading. - Microsoft sign-in needs an Entra app registration and the Microsoft settings before it is switched on.