Add nix flake for linux and macos #78

Merged
puregarlic merged 2 commits from nix-flake into main 2026-03-14 17:37:23 -07:00
Collaborator
No description provided.
seb requested review from puregarlic 2026-03-13 17:05:24 -07:00
seb changed title from WIP: Add nix flake for linux and macos to Add nix flake for linux and macos 2026-03-13 17:05:31 -07:00
Owner

@seb can you push a resolution for the conflict?

@seb can you push a resolution for the conflict?
Implements the Tauri client-side login flow, completes the authentication loop started in #68, and closes #9 and #70.

## What's included

### Auth gRPC integration (`src-tauri/src/auth/`)

**`AuthManager`** — new manager responsible for the full session lifecycle:
- `start_login(server_url, identifier)` — persists the server URL to the store, connects the auth gRPC client, calls `InitiateLogin`, and returns `{ oauth_url, session_id }`
- `await_login(session_id)` — opens the `AwaitLogin` server-streaming call and blocks until the JWT arrives, then stores it in `tauri-plugin-store`
- `get_session()` — single authoritative check for "is the user authenticated?"; returns `Some(Session)` only when both `server-url` and `jwt` are present in the store
- `clear_session()` — atomically removes both store keys on logout

**`Session` struct** — pairs `server_url` and `jwt` as a first-class value. The JWT and server URL are two fields of one fact ("I am logged into this server"), so they are managed together and checked together.

**`start_login` command** — opens the OAuth URL in the system browser via `tauri-plugin-opener` after `InitiateLogin` succeeds.

**`await_login` command** — coordination point between managers: once the JWT lands, triggers `channels.connect(session.server_url)` so the home screen is fully ready without a separate step.

**`get_session` / `logout` commands** — replace `get_server_url` / `set_server_url` for session management.

### Session ownership refactor

`ChannelsManager` previously owned the server URL (stored it in `tauri-plugin-store`, exposed `get_server_url` / `set_server_url`). This was incorrect: the server URL is only meaningful in the context of an authenticated session, and treating it as independent mutable state allowed the app to be in inconsistent positions (URL set, no JWT; JWT set, wrong URL).

Changes:
- `ChannelsManager` no longer holds a store reference or knows about the server URL. `new()` takes no arguments. It is now pure infrastructure: gRPC connectivity, LiveKit rooms, audio.
- `AuthManager` takes over `CONFIG_KEY_SERVER_URL` from the store and persists it in `start_login` (before the browser opens, so it survives a crash mid-flow).
- `set_server_url` / `get_server_url` Tauri commands removed.
- `lib.rs` startup now calls `auth_manager.get_session()` to check for a persisted session and connect channels if one is found.

### `build.rs`

`InitiateLoginResponse` gains `#[serde(rename_all = "camelCase")]` so it serialises as `{ oauthUrl, sessionId }`, matching what the XState actor expects.

### Frontend

**`connect.tsx` / `loginMachine`** — drives the full login flow:
1. User submits server URL + ATProto identifier
2. `start_login` invoke → `{ oauthUrl, sessionId }` returned, browser opens to OAuth URL
3. `await_login(sessionId)` invoke blocks in the background while the user completes OAuth
4. On completion, machine transitions and navigates to `/server`

**`authenticated.tsx`** — `clientLoader` now calls `get_session` instead of `get_server_url`; redirects to `/connect` if no session.

**`settings.tsx`** — "Change Server" calls `logout` and redirects to `/connect` directly.

## Closes

- Closes #9 (server-side OAuth flow was #68; this PR adds the client-side half)
- Closes #70 (login UI in Tauri client)
- Closes #69 (verify JWTs server-side)

## Notes for reviewer

- The `ChannelsManager` will gain an `Arc<AuthManager>` reference when the JWT interceptor is implemented (#69). The dependency direction is `ChannelsManager → AuthManager` (channels needs the JWT, not the other way around). The current refactor intentionally prepares for this without introducing the circular reference that would result from the opposite arrangement.
- `Session` is not yet exported as a TypeScript binding — the `authenticated.tsx` loader uses an inline type. This can be formalised with `ts-rs` when the session shape stabilises.

Co-authored-by: Graham Barber <green.cheese8030@fastmail.com>
Reviewed-on: #74
Reviewed-by: seb <sebastiancbenjamin@gmail.com>
Co-authored-by: Fable <quiet.sign9113@fastmail.com>
Co-committed-by: Fable <quiet.sign9113@fastmail.com>
This PR restricts the group of people who can access a microclimate server from anyone with an Atmosphere identity to only individuals invited to the server.

To support this, it also adds a Server Administration page to the settings route, with a page for adding/removing users from the server. There were new components created to support this, like the Account button for the settings sidebar, and the Atproto Typeahead as suggested previously for #9. They have not been integrated into their original sites yet, pending review.

Closes #75
Closes #73

Reviewed-on: #79
Reviewed-by: seb <sebastiancbenjamin@gmail.com>
Co-authored-by: Graham Barber <green.cheese8030@fastmail.com>
Co-committed-by: Graham Barber <green.cheese8030@fastmail.com>
puregarlic approved these changes 2026-03-14 17:37:20 -07:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
puregarlic/microclimate!78
No description provided.