Skip to content

Commit

Permalink
Adding new permission workflow for granting permissions to the releva…
Browse files Browse the repository at this point in the history
…nt host.
  • Loading branch information
coddingtonbear committed Oct 1, 2023
1 parent fddbb03 commit d31d6e6
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 22 deletions.
28 changes: 26 additions & 2 deletions public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,22 @@ body.popup {
width: 600px;
}

div.auth-field {
width: 90%;
}

div.option-value {
display: flex;
flex-direction: row;
margin-bottom: 10px;
justify-content: space-between;
}

div.option-value.api-key {
div.option-value.host, div.option-value.api-key {
justify-content: left;
}

div.api-key-valid-icon svg {
div.validation-icon svg {
margin-top: 30%;
}

Expand All @@ -52,12 +56,32 @@ div.submit {
}

div.modal {
display: flex;
flex-direction: column;
margin: 50px 100px;
padding: 25px;
overflow-y: scroll;
max-height: calc(100vh - 200px);
}

svg.action-icon {
cursor: pointer;
}

div.permission-modal {
display: flex;
flex-direction: column;
width: 300px;
height: 200px;
padding: 25px;
margin: 0 auto;
margin-top: 25vh;
}

div.modal-content {
flex-grow: 1;
}

div.options-header {
display: flex;
flex-direction: row;
Expand Down
99 changes: 79 additions & 20 deletions src/options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ const Options = () => {
const [method, setMethod] = useState<OutputPreset["method"]>("post");

const [editingPreset, setEditingPreset] = useState<number>();
const [requestingHostPermissionFor, setRequestingHostPermissionFor] =
useState<string>();

const [presets, setPresets] = useState<OutputPreset[]>([]);

Expand Down Expand Up @@ -166,6 +168,7 @@ const Options = () => {
// of populating the form from stored settings. If we are,
// it means you've changed something.
await chrome.storage.local.set({
host,
apiKey,
insecureMode: usedInsecureMode,
} as ExtensionLocalSettings);
Expand All @@ -174,7 +177,7 @@ const Options = () => {
}

handle();
}, [apiKey, hasHostPermission]);
}, [apiKey, host, hasHostPermission]);

useEffect(() => {
if (!loaded) {
Expand Down Expand Up @@ -208,6 +211,7 @@ const Options = () => {
const localSettings = await getLocalSettings(chrome.storage.local);

setHost(localSettings.host);
setTempHost(localSettings.host);
setApiKey(localSettings.apiKey);
setPresets(syncSettings.presets);
setSearchEnabled(syncSettings.searchEnabled);
Expand Down Expand Up @@ -235,7 +239,6 @@ const Options = () => {
}, []);

useEffect(() => {
setTempHost(host);
checkHasHostPermission(host).then((result) => {
setHasHostPermission(result);
});
Expand Down Expand Up @@ -486,35 +489,43 @@ const Options = () => {
<div className="option-value host">
<TextField
label="Hostname"
onBlur={() => setHost(tempHost)}
className="auth-field"
onBlur={() => {
setHost(tempHost);
checkHasHostPermission(tempHost).then((result) => {
setHasHostPermission(result);
if (!result) {
setRequestingHostPermissionFor(tempHost);
}
});
}}
onChange={(event) => setTempHost(event.target.value)}
value={tempHost}
helperText="Hostname on which Obsidian is running (usually 127.0.0.1)."
/>
</div>
{!hasHostPermission && (
<div className="option-value">
<MaterialAlert severity="error">
Obsidian Web does not have permissions to access the host{" "}
{host}.
<Button
onClick={() => {
requestHostPermission(host);
}}
>
Grant Permissions to {host}
</Button>
</MaterialAlert>
<div className="validation-icon">
{!hasHostPermission && (
<Error
className="action-icon"
color="error"
fontSize="large"
titleAccess="Missing permissions. Click to grant."
onClick={() => setRequestingHostPermissionFor(host)}
/>
)}
</div>
)}
</div>
</div>
<div className="option">
<div className="option-value api-key">
<TextField
label="API Key"
className="auth-field"
value={apiKey}
helperText="You can find your API key in the 'Local REST API' section of your settings in Obsidian."
onChange={(event) => setApiKey(event.target.value)}
/>
<div className="api-key-valid-icon">
<div className="validation-icon">
{apiKeyOk && (
<>
{insecureMode && (
Expand All @@ -537,7 +548,15 @@ const Options = () => {
<Error
color="error"
fontSize="large"
titleAccess="Could not connect to the API."
className="action-icon"
onClick={() => {
const tempApiKey = apiKey;
setApiKey("");
setTimeout(() => {
setApiKey(tempApiKey);
}, 1);
}}
titleAccess="Could not connect to the API. Click to retry."
/>
)}
</div>
Expand Down Expand Up @@ -789,6 +808,46 @@ const Options = () => {
)}
</div>
</Paper>
<Modal
open={requestingHostPermissionFor !== undefined}
onClose={() => {
setRequestingHostPermissionFor(undefined);
}}
>
<Paper elevation={3} className="permission-modal">
<div className="modal-content">
<Typography paragraph={true}>
Obsidian Web needs your permission before it can interact with
Obsidian's API on {requestingHostPermissionFor}.
</Typography>
</div>
<div className="submit">
<Button
variant="outlined"
onClick={() => setRequestingHostPermissionFor(undefined)}
>
Cancel
</Button>
{requestingHostPermissionFor && (
<Button
variant="contained"
onClick={() => {
requestHostPermission(requestingHostPermissionFor).then(
(result) => {
setHasHostPermission(result);
if (result) {
setRequestingHostPermissionFor(undefined);
}
}
);
}}
>
Grant Permissions
</Button>
)}
</div>
</Paper>
</Modal>
<Modal
open={editingPreset !== undefined}
onClose={() => closeEditingModal()}
Expand Down

0 comments on commit d31d6e6

Please sign in to comment.