1
0
Fork 0
forked from Mirrors/gomuks

web/rightpanel: add button to track user devices

This commit is contained in:
Tulir Asokan 2024-12-14 00:45:11 +02:00
parent 0fb9805c85
commit 6f3619f632
8 changed files with 47 additions and 2 deletions

View file

@ -90,6 +90,14 @@ func (h *HiClient) handleJSONCommand(ctx context.Context, req *JSONCommand) (any
return unmarshalAndCall(req.Data, func(params *getProfileParams) ([]id.RoomID, error) {
return h.GetMutualRooms(ctx, params.UserID)
})
case "track_user_devices":
return unmarshalAndCall(req.Data, func(params *getProfileParams) (*ProfileEncryptionInfo, error) {
err := h.TrackUserDevices(ctx, params.UserID)
if err != nil {
return nil, err
}
return h.GetProfileEncryptionInfo(ctx, params.UserID)
})
case "get_profile_encryption_info":
return unmarshalAndCall(req.Data, func(params *getProfileParams) (*ProfileEncryptionInfo, error) {
return h.GetProfileEncryptionInfo(ctx, params.UserID)

View file

@ -91,3 +91,8 @@ func (h *HiClient) GetProfileEncryptionInfo(ctx context.Context, userID id.UserI
}
return &resp, nil
}
func (h *HiClient) TrackUserDevices(ctx context.Context, userID id.UserID) error {
_, err := h.Crypto.FetchKeys(ctx, []id.UserID{userID}, true)
return err
}

View file

@ -186,6 +186,10 @@ export default abstract class RPCClient {
return this.request("get_profile_encryption_info", { user_id })
}
trackUserDevices(user_id: UserID): Promise<ProfileEncryptionInfo> {
return this.request("track_user_devices", { user_id })
}
ensureGroupSessionShared(room_id: RoomID): Promise<boolean> {
return this.request("ensure_group_session_shared", { room_id })
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="m354-720-80-80h566v80H354Zm526 520-80-80v-280H640v126l-80-80v-86q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400ZM792-56 688-160h-88q-17 0-28.5-11.5T560-200v-88L240-608v328h240v120H80v-120h80v-408L56-792l56-56 736 736-56 56Zm-72-301Z"/></svg>

After

Width:  |  Height:  |  Size: 365 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z"/></svg>

After

Width:  |  Height:  |  Size: 351 B

View file

@ -135,6 +135,13 @@ div.right-panel-content.user {
display: inline-block;
}
button.action {
padding: .5rem 1rem;
width: 100%;
gap: .25rem;
justify-content: left;
}
div.devices > details > ul {
list-style-type: none;
padding: 0;

View file

@ -73,7 +73,10 @@ const UserInfo = ({ userID }: UserInfoProps) => {
</>}
<DeviceList client={client} room={roomCtx?.store} userID={userID}/>
<hr/>
<UserInfoError errors={errors}/>
{errors?.length ? <>
<UserInfoError errors={errors}/>
<hr/>
</> : null}
</>
}

View file

@ -13,12 +13,13 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { useEffect, useState } from "react"
import { useCallback, useEffect, useState, useTransition } from "react"
import { ScaleLoader } from "react-spinners"
import Client from "@/api/client.ts"
import { RoomStateStore } from "@/api/statestore"
import { ProfileDevice, ProfileEncryptionInfo, TrustState, UserID } from "@/api/types"
import UserInfoError from "./UserInfoError.tsx"
import DevicesIcon from "@/icons/devices.svg?react"
import EncryptedOffIcon from "@/icons/encrypted-off.svg?react"
import EncryptedQuestionIcon from "@/icons/encrypted-question.svg?react"
import EncryptedIcon from "@/icons/encrypted.svg?react"
@ -32,6 +33,18 @@ interface DeviceListProps {
const DeviceList = ({ client, room, userID }: DeviceListProps) => {
const [view, setEncryptionInfo] = useState<ProfileEncryptionInfo | null>(null)
const [errors, setErrors] = useState<string[] | null>(null)
const [trackChangePending, startTransition] = useTransition()
const doTrackDeviceList = useCallback(() => {
startTransition(async () => {
try {
const resp = await client.rpc.trackUserDevices(userID)
setEncryptionInfo(resp)
setErrors(resp.errors)
} catch (err) {
setErrors([`${err}`])
}
})
}, [client, userID])
useEffect(() => {
setEncryptionInfo(null)
setErrors(null)
@ -60,6 +73,9 @@ const DeviceList = ({ client, room, userID }: DeviceListProps) => {
<h4>Security</h4>
<p>{encryptionMessage}</p>
<p>This user's device list is not being tracked.</p>
<button className="action" onClick={doTrackDeviceList} disabled={trackChangePending}>
<DevicesIcon /> Start tracking device list
</button>
<UserInfoError errors={errors}/>
</div>
}