···55 withSliceAccess,
66} from "../../../routes/slice-middleware.ts";
77import { getSliceClient } from "../../../utils/client.ts";
88-import { atprotoClient } from "../../../config.ts";
88+import { publicClient } from "../../../config.ts";
99import { renderHTML } from "../../../utils/render.tsx";
1010import { Layout } from "../../../shared/fragments/Layout.tsx";
1111import { extractSliceParams } from "../../../utils/slice-params.ts";
···8989 const handle = url.searchParams.get("handle");
9090 const isCompact = url.searchParams.get("compact") === "true";
91919292- // Fetch jetstream status using the atproto client
9393- const data = await atprotoClient.network.slices.slice.getJetstreamStatus();
9292+ // Fetch jetstream status using the public client
9393+ const data = await publicClient.network.slices.slice.getJetstreamStatus();
94949595 // Render compact version for logs page
9696 if (isCompact) {
···11import type { Route } from "@std/http/unstable-route";
22import { withAuth } from "../../../routes/middleware.ts";
33-import { atprotoClient } from "../../../config.ts";
33+import { createSessionClient, publicClient } from "../../../config.ts";
44import { buildSliceUri } from "../../../utils/at-uri.ts";
55import { renderHTML } from "../../../utils/render.tsx";
66import { hxRedirect } from "../../../utils/htmx.ts";
···7777 // Construct the URI for this slice
7878 const sliceUri = buildSliceUri(context.currentUser.sub!, sliceId);
79798080- // Get the current record first
8181- const currentRecord = await atprotoClient.network.slices.slice.getRecord({
8080+ // Get the current record first (read operation, use public client)
8181+ const currentRecord = await publicClient.network.slices.slice.getRecord({
8282 uri: sliceUri,
8383 });
84848585+ // Create user-scoped client for write operation
8686+ const sessionClient = createSessionClient(context.currentUser.sessionId!);
8787+8588 // Update the record with new name and domain
8686- await atprotoClient.network.slices.slice.updateRecord(sliceId, {
8989+ await sessionClient.network.slices.slice.updateRecord(sliceId, {
8790 ...currentRecord.value,
8891 name: name.trim(),
8992 domain: domain.trim(),
···115118 }
116119117120 try {
121121+ // Create user-scoped client for delete operation
122122+ const sessionClient = createSessionClient(context.currentUser.sessionId!);
123123+118124 // Delete the slice record from AT Protocol
119119- await atprotoClient.network.slices.slice.deleteRecord(sliceId);
125125+ await sessionClient.network.slices.slice.deleteRecord(sliceId);
120126121127 return hxRedirect(`/profile/${context.currentUser.handle}`);
122128 } catch (_error) {
+2-2
frontend/src/features/slices/sync/handlers.tsx
···33import { requireAuth, withAuth } from "../../../routes/middleware.ts";
44import { getSliceClient } from "../../../utils/client.ts";
55import { buildSliceUri } from "../../../utils/at-uri.ts";
66-import { atprotoClient } from "../../../config.ts";
66+import { publicClient } from "../../../config.ts";
77import {
88 requireSliceAccess,
99 withSliceAccess,
···226226227227 // Get slice info for domain comparison
228228 const sliceUri = buildSliceUri(context.currentUser.sub!, sliceId);
229229- const sliceRecord = await atprotoClient.network.slices.slice.getRecord({
229229+ const sliceRecord = await publicClient.network.slices.slice.getRecord({
230230 uri: sliceUri,
231231 });
232232 const sliceDomain = sliceRecord.value.domain;
+8-4
frontend/src/routes/middleware.ts
···11-import { atprotoClient, sessionStore } from "../config.ts";
11+import { sessionStore, createSessionClient } from "../config.ts";
22import { recordBlobToCdnUrl } from "@slices/client";
33import { getSliceActor } from "../lib/api.ts";
4455export interface AuthenticatedUser {
66+ sessionId?: string;
67 handle?: string;
78 sub?: string;
89 isAuthenticated: boolean;
···1920 const currentUser = await sessionStore.getCurrentUser(req);
20212122 // If user is authenticated, try to fetch their profile data
2222- if (currentUser.isAuthenticated && currentUser.sub) {
2323+ if (currentUser.isAuthenticated && currentUser.sessionId && currentUser.sub) {
2424+ // Create session-scoped client
2525+ const sessionClient = createSessionClient(currentUser.sessionId);
2626+2327 try {
2428 // Get the user's profile from network.slices.actor.profile
2525- const profile = await getSliceActor(atprotoClient, currentUser.sub);
2929+ const profile = await getSliceActor(sessionClient, currentUser.sub);
2630 if (profile) {
2731 currentUser.displayName = profile.displayName;
2832 currentUser.avatar = profile.avatar;
···3539 // Fallback to Bluesky profile for avatar if not found in slices profile
3640 if (!currentUser.avatar) {
3741 try {
3838- const profileRecords = await atprotoClient.app.bsky.actor.profile
4242+ const profileRecords = await sessionClient.app.bsky.actor.profile
3943 .getRecords({
4044 where: {
4145 did: { eq: currentUser.sub },
+8-4
frontend/src/utils/client.ts
···11import { AtProtoClient } from "../client.ts";
22-import { atprotoClient } from "../config.ts";
22+import { createOAuthClient } from "../config.ts";
33import { buildAtUri } from "./at-uri.ts";
4455interface AuthContext {
66 currentUser: {
77+ sessionId?: string;
78 sub?: string;
89 };
910}
···3031 });
31323233 // Use authenticated client if user is authenticated, otherwise public client
3333- return context.currentUser.sub
3434- ? new AtProtoClient(API_URL, sliceUri, atprotoClient.oauth)
3535- : new AtProtoClient(API_URL, sliceUri);
3434+ if (context.currentUser.sessionId) {
3535+ const sessionOAuthClient = createOAuthClient(context.currentUser.sessionId);
3636+ return new AtProtoClient(API_URL, sliceUri, sessionOAuthClient);
3737+ } else {
3838+ return new AtProtoClient(API_URL, sliceUri);
3939+ }
3640}