Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
We'll document all notable changes in this file, including bug fixes, enhancements, and dependency updates.
Dates should be in`YYYY-MM-DD` format and versions are in [semantic versioning](http://semver.org/) format.

## v0.10.7 2026-11-07

### Fixed

- People who aren't members of a public organization can now see its roles and who holds them.

## v0.10.6 2026-11-07

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "adminima",
"version": "0.10.6",
"version": "0.10.7",
"private": true,
"scripts": {
"dev": "vite dev",
Expand Down
5 changes: 2 additions & 3 deletions src/lib/ARCI.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@

const orgContext = getOrg();

// Mirrors the roles RLS policy: only members, or anyone if the org is public, can see its roles.
// Without them, every assignment would render as "Unknown role", so show nothing instead.
let canSeeRoles = $derived(orgContext().member || orgContext().org.visibility === 'public');
// Without the org's roles, every assignment would render as "Unknown role", so show nothing.
let canSeeRoles = $derived(orgContext().visible);

const dbContext = getDB();
const db = $derived(dbContext());
Expand Down
9 changes: 4 additions & 5 deletions src/lib/Changes.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,16 @@
let { changes, profiles, children }: Props = $props();

const context = getOrg();
let org = $derived(context().org);

const dbContext = getDB();
const db = $derived(dbContext());

const user = getUser();
const Levels = { triage: 0, active: 1, blocked: 2, done: 4, backlog: 3, declined: 5 };

let visible = $derived(
($user === null && org.visibility === 'public') || ($user !== null && context().member)
);
let visible = $derived(context().visible);
// Only members can change a change's status; everyone else sees it read-only.
let canEditStatus = $derived($user !== null && context().member);

let filterText = $state(getInitialTextFilter());
let filterStatus = $state<undefined | StatusType>(getInitialStatusFilter());
Expand Down Expand Up @@ -214,7 +213,7 @@
{@const comment = latestComments.find((c) => c.id === change.comments.at(-1))}
<tr>
<td
>{#if visible}
>{#if canEditStatus}
<StatusChooser
tip="Change the status of this change"
value={change.status}
Expand Down
7 changes: 7 additions & 0 deletions src/routes/org/[orgid]/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
org: OrganizationRow;
admin: boolean;
member: boolean;
/**
* Whether the viewer can see the whole organization, not just its public items: its roles,
* who holds them, and all of its processes and changes. Mirrors the SELECT policies on
* roles, assignments and processes: members, or anyone if the organization is public.
*/
visible: boolean;
counts: {
roles: number;
profiles: number;
Expand Down Expand Up @@ -42,6 +48,7 @@
org: data.org,
admin: data.admin,
member: data.member,
visible: data.member || data.org.visibility === 'public',
counts: data.counts,
shortRoles: data.shortRoles,
shortProcesses: data.shortProcesses
Expand Down
3 changes: 1 addition & 2 deletions src/routes/org/[orgid]/process/[processid]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@
// This mirrors the row-level security policy: only admins and people with an accountable or responsible role can edit this policy.
let isAdmin = $derived(orgContext().admin);
let isMember = $derived(orgContext().member);
// Mirrors the roles RLS policy; without roles, assignments would all render as "Unknown role".
let canSeeRoles = $derived(isMember || orgContext().org.visibility === 'public');
let canSeeRoles = $derived(orgContext().visible);
let accountable = $derived(
$user !== null &&
process !== null &&
Expand Down
4 changes: 1 addition & 3 deletions src/routes/org/[orgid]/processes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@

let isAdmin = $derived($user && orgContext().admin);

let visible = $derived(
($user === null && org.visibility === 'public') || ($user !== null && orgContext().member)
);
let visible = $derived(orgContext().visible);

let filter = $state(getInitialTextFilter());
let lowerFilter = $derived(filter.toLocaleLowerCase().trim());
Expand Down
4 changes: 1 addition & 3 deletions src/routes/org/[orgid]/role/[roleid]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@
let profiles = $derived(Organization.getRoleProfiles(role.id, assignments, allProfiles));
let isAdmin = $derived($user && orgContext().admin);

let visible = $derived(
($user === null && org.visibility === 'public') || ($user !== null && orgContext().member)
);
let visible = $derived(orgContext().visible);
</script>

<Title
Expand Down
9 changes: 2 additions & 7 deletions src/routes/org/[orgid]/roles/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import RoleLink from '#lib/RoleLink.svelte';
import Field from '#lib/Field.svelte';
import { getDB, getUser } from '#routes/+layout.svelte';
import { getDB } from '#routes/+layout.svelte';
import { getOrg } from '#routes/org/[orgid]/+layout.svelte';
import { mutate } from '#routes/errors.svelte.ts';
import Title from '#lib/Title.svelte';
Expand All @@ -29,17 +29,12 @@
const dbContext = getDB();
const db = $derived(dbContext());

const user = getUser();

let newRole: string = $state('');
let filter: string = $state('');
let lowerFilter = $derived(filter.toLocaleLowerCase().trim());
let path = $derived(Organization.getPath(org));

/** Roles are visible if the org is public or the authenticated user is in the org. */
let visible = $derived(
($user === null && org.visibility === 'public') || ($user !== null && orgContext().member)
);
let visible = $derived(orgContext().visible);

async function createRole() {
const { data } = await mutate(
Expand Down
Loading