Skip to content

Commit

Permalink
feat: add cancel authorization request functionality and improve UI c…
Browse files Browse the repository at this point in the history
…omponents (#1491)
  • Loading branch information
F-OBrien authored Dec 20, 2024
1 parent 6f29ec7 commit 52acbc8
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 83 deletions.
17 changes: 17 additions & 0 deletions packages/extension-base/src/background/handlers/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,8 @@ export default class Extension {
return { list: remAuth };
}

// Reject the authorization request and add the URL to the authorized list with no keys.
// The site will not prompt for re-authorization on future visits.
private rejectAuthRequest (id: string): void {
const queued = this.#state.getAuthRequest(id);

Expand All @@ -534,6 +536,18 @@ export default class Extension {
reject(new Error('Rejected'));
}

// Cancel the authorization request and do not add the URL to the authorized list.
// The site will prompt for authorization on future visits.
private cancelAuthRequest (id: string): void {
const queued = this.#state.getAuthRequest(id);

assert(queued, 'Unable to find request');

const { reject } = queued;

reject(new Error('Cancelled'));
}

private updateCurrentTabs ({ urls }: RequestActiveTabsUrlUpdate) {
this.#state.updateCurrentTabsUrl(urls);
}
Expand All @@ -558,6 +572,9 @@ export default class Extension {
case 'pri(authorize.reject)':
return this.rejectAuthRequest(request as string);

case 'pri(authorize.cancel)':
return this.cancelAuthRequest(request as string);

case 'pri(authorize.requests)':
return port && this.authorizeSubscribe(id, port);

Expand Down
10 changes: 8 additions & 2 deletions packages/extension-base/src/background/handlers/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,14 @@ export default class State {
return {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
reject: async (error: Error): Promise<void> => {
await complete();
reject(error);
if (error.message === 'Cancelled') {
delete this.#authRequests[id];
this.updateIconAuth(true);
reject(new Error('Connection request was cancelled by the user.'));
} else {
await complete();
reject(new Error('Connection request was rejected by the user.'));
}
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
resolve: async ({ authorizedAccounts, result }: AuthResponse): Promise<void> => {
Expand Down
1 change: 1 addition & 0 deletions packages/extension-base/src/background/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export interface RequestSignatures {
'pri(authorize.requests)': [RequestAuthorizeSubscribe, boolean, AuthorizeRequest[]];
'pri(authorize.remove)': [string, ResponseAuthorizeList];
'pri(authorize.reject)': [string, void];
'pri(authorize.cancel)': [string, void];
'pri(authorize.update)': [RequestUpdateAuthorizedAccounts, void];
'pri(activeTabsUrl.update)': [RequestActiveTabsUrlUpdate, void];
'pri(connectedTabsUrl.get)': [null, ConnectedTabsUrlResponse];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,41 +42,54 @@ function AccountManagement ({ className }: Props): React.ReactElement<Props> {
);

return (
<>
<div className={`${className}`}>
<Header
showBackArrow
smallMargin={true}
text={t('Accounts connected to {{url}}', { replace: { url } })}
/>
<div className={className}>
<div className='content'>
<AccountSelection
className='accountSelection'
origin={origin}
origin={url}
showHidden={true}
url={url}
withWarning={false}
/>
<Button
className='acceptButton'
onClick={_onApprove}
>
{t('Connect {{total}} account(s)', { replace: {
total: selectedAccounts.length
} })}
</Button>
<div className='footer'>
<Button
className='acceptButton'
onClick={_onApprove}
>
{t('Connect {{total}} account(s)', { replace: {
total: selectedAccounts.length
} })}
</Button>
</div>
</div>
</>
</div>
);
}

export default styled(AccountManagement)<Props>`
.accountSelection{
.accountList{
height: 390px;
}
display: flex;
flex-direction: column;
height: 100%;
min-height: 550px;
.content {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}
.footer {
background: var(--background);
flex-shrink: 0;
}
.acceptButton {
width: 90%;
margin: 0.5rem auto 0;
margin: 0.5rem auto;
}
`;
108 changes: 72 additions & 36 deletions packages/extension-ui/src/Popup/Authorize/Request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@

import type { RequestAuthorizeTab } from '@polkadot/extension-base/background/types';

import React, { useCallback, useContext, useEffect } from 'react';
import React, { useCallback, useContext, useEffect, useState } from 'react';

import { AccountContext, ActionBar, ActionContext, Button, Link } from '../../components/index.js';
import { AccountContext, ActionContext, Button } from '../../components/index.js';
import { useTranslation } from '../../hooks/index.js';
import { approveAuthRequest, rejectAuthRequest } from '../../messaging.js';
import { approveAuthRequest, cancelAuthRequest, rejectAuthRequest } from '../../messaging.js';
import { AccountSelection } from '../../partials/index.js';
import { styled } from '../../styled.js';
import NoAccount from './NoAccount.js';

interface Props {
authId: string;
className?: string;
isFirst: boolean;
request: RequestAuthorizeTab;
url: string;
}

function Request ({ authId, className, isFirst, request: { origin }, url }: Props): React.ReactElement<Props> {
function Request ({ authId, className, request: { origin }, url }: Props): React.ReactElement<Props> {
const { accounts, selectedAccounts = [], setSelectedAccounts } = useContext(AccountContext);
const { t } = useTranslation();
const onAction = useContext(ActionContext);
const [dontAskAgain, setDontAskAgain] = useState(false);

useEffect(() => {
const defaultAccountSelection = accounts
Expand All @@ -42,13 +42,22 @@ function Request ({ authId, className, isFirst, request: { origin }, url }: Prop
[authId, onAction, selectedAccounts]
);

const _onClose = useCallback(
const _onReject = useCallback(
(): void => {
rejectAuthRequest(authId)
const rejectFunction = dontAskAgain ? rejectAuthRequest : cancelAuthRequest;

rejectFunction(authId)
.then(() => onAction())
.catch((error: Error) => console.error(error));
},
[authId, onAction]
[authId, onAction, dontAskAgain]
);

const _onToggleDontAskAgain = useCallback(
(): void => {
setDontAskAgain((prev) => !prev);
},
[]
);

if (!accounts.length) {
Expand All @@ -61,42 +70,69 @@ function Request ({ authId, className, isFirst, request: { origin }, url }: Prop
origin={origin}
url={url}
/>
{isFirst && (
<Button
className='acceptButton'
onClick={_onApprove}
>
{t('Connect {{total}} account(s)', { replace: {
total: selectedAccounts.length
} })}
</Button>
)}
<ActionBar className='rejectionButton'>
<Link
className='closeLink'
isDanger
onClick={_onClose}
>
{t('Reject')}
</Link>
</ActionBar>
<div className='footer'>
<div className='buttonContainer'>
<Button
className='acceptButton'
onClick={_onApprove}
>
{t('Connect {{total}} account(s)', { replace: {
total: selectedAccounts.length
} })}
</Button>
<Button
className='rejectButton'
isDanger
onClick={_onReject}
>
{t('Reject')}
</Button>
</div>
<div className='dontAskAgainContainer'>
<input
checked={dontAskAgain}
onChange={_onToggleDontAskAgain}
type='checkbox'
/>
<label>{t("Don't ask again")}</label>
</div>
</div>
</div>

);
}

export default styled(Request)<Props>`
.acceptButton {
width: 90%;
margin: .5rem auto 0;
display: flex;
flex-direction: column;
flex: 1;
overflow-y: auto;
.footer {
padding: 1rem 1rem 0rem 1rem;
background: var(--background);
}
.buttonContainer {
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: 0.5rem;
}
.acceptButton, .rejectButton {
width: 48%;
height: 40px;
}
.rejectionButton {
margin: 0 0 15px 0;
text-decoration: underline;
.dontAskAgainContainer {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
.closeLink {
margin: auto;
padding: 0;
input {
margin-right: 0.5rem;
}
}
`;
Loading

0 comments on commit 52acbc8

Please sign in to comment.