Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tloncorp/landscape
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 31b1cacb193421810bf42e28056161e75574207a
Choose a base ref
..
head repository: tloncorp/landscape
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2ebd600a272ee2ab180c30f672386a1d65bd7430
Choose a head ref
12 changes: 8 additions & 4 deletions ui/src/gear/permissions/lib.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Poke } from "@urbit/http-api";
import { ApprovePermsPoke, DenyPermsPoke, Passport, Perm, PokePerm, Seal } from "./types";
import { ApprovePermsPoke, DenyPermsPoke, Passport, PokePerm, Seal } from "./types";
import api from "@/api";

export function approvePerms(desk: string, perms: PokePerm[]): Poke<ApprovePermsPoke> {
@@ -24,11 +24,15 @@ export function denyPerms(desk: string, perms: PokePerm[]): Poke<DenyPermsPoke>
};
}

export async function sealToPassport(seal: Seal) {
return await api.thread<Passport, Seal>({
export async function sealToPassport(desk: string, seal: Seal) {
console.log('sealToPassport', { desk, seal })
return await api.thread<Passport, { desk: string, seal: Seal }>({
inputMark: "json",
outputMark: "json",
threadName: "get-passport",
body: seal
body: {
desk,
seal
}
});
}
73 changes: 33 additions & 40 deletions ui/src/gear/permissions/types.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,50 @@

type PermType = "super" | "watch" | "write" | "reads" | "press";

type Vane = 'ames' | 'behn' | 'clay' | 'dill' | 'eyre' | 'fine' | 'gall' | 'iris' | 'jael' | 'khan';

type Tail = {
jump?: boolean;
care?: string | null;
desk?: string | null;
dude?: string | null;
path?: string | null;
ship?: string | null;
spur?: string | null;
vane?: string | null;
} | null;


export interface Perm {
name: PermType;
vane: Vane | null;
tail: Tail;
}
/**
* A jammed noun representing a permission. base64 encoded. Not consumed by
* the frontend. Used when querying for passport or when approving / denying
* perms.
*/
type Perm = string;

export type Seal = Perm[];

export interface PermSummary {
/**
* Passport-formatted permissions
*/

/**
* Permission summary
*/
interface Pes {
desc: string;
// TODO: per tinnus, "have" is meant to say whether the app already has all /
// any of / none of the perms in question but currently it doesn't, it just
// always says nil.
have: "nil"
// always says "nil".
have: string;
pers: Perm[];
warn: string | null;
}

/**
* Passport-formatted permissions
* Permission bucket
*/
interface AppPerm {
pes: {
node: PermSummary[]
};
app: string;
interface Kind {
nom: string;
pes: Pes[];
// TODO: add a field to indicate which icon to render in the modal
}

interface KindPerm {
kind: {
nom: string;
pes: PermSummary[]
}
kind: Kind;
}

interface NodePerm {
node: PermSummary;
node: Pes;
}

export type PassportPerm = KindPerm | NodePerm;
export type AppPerm = {
app: string;
pes: Pes[];
}

/**
@@ -62,19 +55,19 @@ export interface Passport {
/**
* Categorized perms
*/
rad: KindPerm[];
rad: PassportPerm[];
/**
* Dangerous perms
*/
sys: (KindPerm | NodePerm )[];
sys: PassportPerm[];
/**
* All apps perms
*/
any: KindPerm[];
any: PassportPerm[];
/**
* Unknown app perms
*/
new: KindPerm[];
new: PassportPerm[];
/**
* Specific app perms
*/
4 changes: 4 additions & 0 deletions ui/src/logic/utils.ts
Original file line number Diff line number Diff line change
@@ -127,3 +127,7 @@ export function randomElement<T>(a: T[]) {
export function randomIntInRange(min: number, max: number) {
return Math.round(Math.random() * (max - min) + min);
}

export function capFirst(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
13 changes: 8 additions & 5 deletions ui/src/permissions/PermissionsDialog.tsx
Original file line number Diff line number Diff line change
@@ -27,6 +27,10 @@ export function PermissionsDialogInner({
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const showWarning = passport.sys.length > 0;

const passportPerms = [...passport.sys, ...passport.any, ...passport.new, ...passport.rad, ...passport.app];

// console.log(passportPerms);

return (
<div className="space-y-6">
<section className='flex justify-between items-center'>
@@ -55,11 +59,10 @@ export function PermissionsDialogInner({
viewMode === 'Summary' ? (
<div className="space-y-5">
{
// [...passport.sys, ...passport.any, ...passport.new, ...passport.rad].map(p => {
[...passport.rad].map(p => {
return p.kind.pes.map((pe, i) => {
return <SummaryRow key={i} summary={pe} />
})
passportPerms.map((p, i) => {
return (
<SummaryRow key={i} perm={p} />
)
})
}
</div>
67 changes: 46 additions & 21 deletions ui/src/permissions/SummaryRow.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,81 @@
import { Adjust } from '@/components/icons/Adjust';
import BellIcon from '@/components/icons/BellIcon';
import { ChevronDown16Icon } from '@/components/icons/ChevronDown16Icon';
import GlobeIcon from '@/components/icons/GlobeIcon';
import KeyIcon from '@/components/icons/KeyIcon';
import SigIcon from '@/components/icons/SigIcon';
import ZapIcon from '@/components/icons/ZapIcon';
import { PermSummary } from '@/gear';
import React from 'react';
import { AppPerm, PassportPerm } from '@/gear';
import { capFirst } from '@/logic/utils';
import React, { useState } from 'react';

interface SummaryRowProps {
/**
* A permission summary.
* A permission bucket.
*/
summary: PermSummary;
perm: PassportPerm | AppPerm;
}

// TODO: figured out mapping from permission to icon from Dan & Mark
const iconFromPerm = (perm: PermSummary) => {
if(perm.pers.some(p => p.vane && ['ames', 'eyre', 'gall'].includes(p.vane))) {
return <GlobeIcon />;
}
// TODO: need icon identifier from perm; requested from tinnus
const iconFromPerm = (perm: PassportPerm) => {
// for now, return random icon
const rand = Math.random();

if(perm.pers.some(p => p.vane && p.vane === 'jael')) {
if(rand < 0.2) {
return <GlobeIcon />;
} else if(rand < 0.4) {
return <KeyIcon />;
} else if(rand < 0.6) {
return <BellIcon />;
} else if(rand < 0.8) {
return <SigIcon />;
} else {
return <Adjust />;
}

// TODO:
// <BellIcon />
// <SigIcon />

return <Adjust />;
}

// function DetailRow({ summary }: { detail: string }) {

/**
* A row summarizing a requested permission.
* It has the description of the permission and an optional warning icon.
*/
export default function SummaryRow({ summary }: SummaryRowProps) {
const { desc, warn } = summary;
export default function SummaryRow({ perm }: SummaryRowProps) {
// TODO: handle node perms
if('node' in perm) {
return null;
}

// TODO: handle app perms
if('app' in perm) {
return null;
}

const { nom, pes } = perm.kind;
const [expanded, setExpanded] = useState(false);
const hasWarning = pes.some(pe => pe.warn !== null);

return (
<div className='w-full flex justify-between content-center p-2 space-x-4'>
<div className='flex space-x-1'>
<div className='h-8 w-8 bg-gray-50 p-1.5'>
{iconFromPerm(summary)}
{iconFromPerm(perm)}
</div>
<div className='flex flex-col justify-center text-sm font-medium text-gray-900'>
{desc}
{capFirst(nom)}
</div>
</div>
{warn ? (
{hasWarning ? (
<div className='flex flex-col justify-center'>
<ZapIcon color='#FF6240' />
</div>
) : null}
{/* A clickable toggle that will set the expanded state. It should use the ChevronDown icon. When expanded, it should apply a rotation of -180 */}
<div className='flex flex-col justify-center'>
<button onClick={() => setExpanded(!expanded)}>
<ChevronDown16Icon className={`transform ${expanded ? 'rotate-180' : ''}`} />
</button>
</div>
</div>
)
}
7 changes: 4 additions & 3 deletions ui/src/permissions/usePassport.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Passport, Seal, sealToPassport } from "@/gear";
import { useEffect, useState } from "react";

export default function usePassport({ seal }: { seal: Seal }) {
export default function usePassport({ desk, seal }: { desk: string, seal: Seal }) {
const [passport, setPassport] = useState<Passport | null>(null);

const fetchPassport = async () => {
const response = await sealToPassport(seal);
console.log('response', response);
console.log('fetching passport...');
const response = await sealToPassport(desk, seal);
console.log('response', response)
setPassport(response);
};

2 changes: 1 addition & 1 deletion ui/src/permissions/usePermissions.ts
Original file line number Diff line number Diff line change
@@ -14,8 +14,8 @@ export default function usePermissions() {
const treaty = useTreaty(host, desk);
const docket = charge || treaty;
const appName = getAppName(docket);
const { passport } = usePassport({ seal: treaty?.seal });
const [ship,] = useRemoteDesk(docket, pike, treaty?.ship);
const { passport } = usePassport({ desk, seal: treaty?.seal });
const installStatus = useInstallStatus(docket);
const [presentableSeal, setPresentableSeal] = useState<string[] | null>(null);