kopia lustrzana https://github.com/cheeaun/phanpy
Allow revoke access token
- Also means storing client credentials - A bit of cleaning up for vapid key as it's everywhere nowpull/1176/head
rodzic
35af0a0e84
commit
e7ffccf9d1
11
src/app.jsx
11
src/app.jsx
|
@ -63,7 +63,9 @@ import states, { initStates, statusKey } from './utils/states';
|
||||||
import store from './utils/store';
|
import store from './utils/store';
|
||||||
import {
|
import {
|
||||||
getAccount,
|
getAccount,
|
||||||
|
getCredentialApplication,
|
||||||
getCurrentAccount,
|
getCurrentAccount,
|
||||||
|
getVapidKey,
|
||||||
setCurrentAccountID,
|
setCurrentAccountID,
|
||||||
} from './utils/store-utils';
|
} from './utils/store-utils';
|
||||||
|
|
||||||
|
@ -367,9 +369,12 @@ function App() {
|
||||||
window.location.pathname || '/',
|
window.location.pathname || '/',
|
||||||
);
|
);
|
||||||
|
|
||||||
const clientID = store.sessionCookie.get('clientID');
|
const {
|
||||||
const clientSecret = store.sessionCookie.get('clientSecret');
|
client_id: clientID,
|
||||||
const vapidKey = store.sessionCookie.get('vapidKey');
|
client_secret: clientSecret,
|
||||||
|
vapid_key,
|
||||||
|
} = getCredentialApplication(instanceURL) || {};
|
||||||
|
const vapidKey = getVapidKey(instanceURL) || vapid_key;
|
||||||
const verifier = store.sessionCookie.get('codeVerifier');
|
const verifier = store.sessionCookie.get('codeVerifier');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import Menu2 from '../components/menu2';
|
||||||
import NameText from '../components/name-text';
|
import NameText from '../components/name-text';
|
||||||
import RelativeTime from '../components/relative-time';
|
import RelativeTime from '../components/relative-time';
|
||||||
import { api } from '../utils/api';
|
import { api } from '../utils/api';
|
||||||
|
import { revokeAccessToken } from '../utils/auth';
|
||||||
import niceDateTime from '../utils/nice-date-time';
|
import niceDateTime from '../utils/nice-date-time';
|
||||||
import states from '../utils/states';
|
import states from '../utils/states';
|
||||||
import store from '../utils/store';
|
import store from '../utils/store';
|
||||||
|
@ -185,9 +186,15 @@ function Accounts({ onClose }) {
|
||||||
}
|
}
|
||||||
disabled={!isCurrent}
|
disabled={!isCurrent}
|
||||||
menuItemClassName="danger"
|
menuItemClassName="danger"
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
// const yes = confirm('Log out?');
|
// const yes = confirm('Log out?');
|
||||||
// if (!yes) return;
|
// if (!yes) return;
|
||||||
|
await revokeAccessToken({
|
||||||
|
instanceURL: account.instanceURL,
|
||||||
|
client_id: account.clientId,
|
||||||
|
client_secret: account.clientSecret,
|
||||||
|
token: account.accessToken,
|
||||||
|
});
|
||||||
accounts.splice(i, 1);
|
accounts.splice(i, 1);
|
||||||
store.local.setJSON('accounts', accounts);
|
store.local.setJSON('accounts', accounts);
|
||||||
// location.reload();
|
// location.reload();
|
||||||
|
|
|
@ -18,6 +18,10 @@ import {
|
||||||
} from '../utils/auth';
|
} from '../utils/auth';
|
||||||
import { supportsPKCE } from '../utils/oauth-pkce';
|
import { supportsPKCE } from '../utils/oauth-pkce';
|
||||||
import store from '../utils/store';
|
import store from '../utils/store';
|
||||||
|
import {
|
||||||
|
getCredentialApplication,
|
||||||
|
storeCredentialApplication,
|
||||||
|
} from '../utils/store-utils';
|
||||||
import useTitle from '../utils/useTitle';
|
import useTitle from '../utils/useTitle';
|
||||||
|
|
||||||
const { PHANPY_DEFAULT_INSTANCE: DEFAULT_INSTANCE } = import.meta.env;
|
const { PHANPY_DEFAULT_INSTANCE: DEFAULT_INSTANCE } = import.meta.env;
|
||||||
|
@ -87,19 +91,20 @@ function Login() {
|
||||||
|
|
||||||
setUIState('loading');
|
setUIState('loading');
|
||||||
try {
|
try {
|
||||||
const { client_id, client_secret, vapid_key } =
|
let credentialApplication = getCredentialApplication(instanceURL);
|
||||||
await registerApplication({
|
if (!credentialApplication) {
|
||||||
|
credentialApplication = await registerApplication({
|
||||||
instanceURL,
|
instanceURL,
|
||||||
});
|
});
|
||||||
|
storeCredentialApplication(instanceURL, credentialApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { client_id, client_secret } = credentialApplication;
|
||||||
|
|
||||||
const authPKCE = await supportsPKCE({ instanceURL });
|
const authPKCE = await supportsPKCE({ instanceURL });
|
||||||
console.log({ authPKCE });
|
console.log({ authPKCE });
|
||||||
if (authPKCE) {
|
if (authPKCE) {
|
||||||
if (client_id && client_secret) {
|
if (client_id && client_secret) {
|
||||||
store.sessionCookie.set('clientID', client_id);
|
|
||||||
store.sessionCookie.set('clientSecret', client_secret);
|
|
||||||
store.sessionCookie.set('vapidKey', vapid_key);
|
|
||||||
|
|
||||||
const [url, verifier] = await getPKCEAuthorizationURL({
|
const [url, verifier] = await getPKCEAuthorizationURL({
|
||||||
instanceURL,
|
instanceURL,
|
||||||
client_id,
|
client_id,
|
||||||
|
@ -111,10 +116,6 @@ function Login() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (client_id && client_secret) {
|
if (client_id && client_secret) {
|
||||||
store.sessionCookie.set('clientID', client_id);
|
|
||||||
store.sessionCookie.set('clientSecret', client_secret);
|
|
||||||
store.sessionCookie.set('vapidKey', vapid_key);
|
|
||||||
|
|
||||||
location.href = await getAuthorizationURL({
|
location.href = await getAuthorizationURL({
|
||||||
instanceURL,
|
instanceURL,
|
||||||
client_id,
|
client_id,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import {
|
||||||
import showToast from '../utils/show-toast';
|
import showToast from '../utils/show-toast';
|
||||||
import states from '../utils/states';
|
import states from '../utils/states';
|
||||||
import store from '../utils/store';
|
import store from '../utils/store';
|
||||||
import { getAPIVersions } from '../utils/store-utils';
|
import { getAPIVersions, getVapidKey } from '../utils/store-utils';
|
||||||
import supports from '../utils/supports';
|
import supports from '../utils/supports';
|
||||||
|
|
||||||
const DEFAULT_TEXT_SIZE = 16;
|
const DEFAULT_TEXT_SIZE = 16;
|
||||||
|
@ -860,6 +860,9 @@ function Settings({ onClose }) {
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
<p>Debugging</p>
|
<p>Debugging</p>
|
||||||
|
<p>
|
||||||
|
<b>Vapid key</b>: {getVapidKey()}
|
||||||
|
</p>
|
||||||
{__BENCH_RESULTS?.size > 0 && (
|
{__BENCH_RESULTS?.size > 0 && (
|
||||||
<ul>
|
<ul>
|
||||||
{Array.from(__BENCH_RESULTS.entries()).map(
|
{Array.from(__BENCH_RESULTS.entries()).map(
|
||||||
|
|
|
@ -105,3 +105,32 @@ export async function getAccessToken({
|
||||||
console.log({ tokenJSON });
|
console.log({ tokenJSON });
|
||||||
return tokenJSON;
|
return tokenJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function revokeAccessToken({
|
||||||
|
instanceURL,
|
||||||
|
client_id,
|
||||||
|
client_secret,
|
||||||
|
token,
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
client_id,
|
||||||
|
client_secret,
|
||||||
|
token,
|
||||||
|
});
|
||||||
|
|
||||||
|
const revokeResponse = await fetch(`https://${instanceURL}/oauth/revoke`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: params.toString(),
|
||||||
|
keepalive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return revokeResponse.ok;
|
||||||
|
} catch (error) {
|
||||||
|
console.erro('Error revoking token', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -169,9 +169,11 @@ export function getAPIVersions() {
|
||||||
return instance?.apiVersions || {};
|
return instance?.apiVersions || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getVapidKey() {
|
export function getVapidKey(instance) {
|
||||||
// Vapid key has moved from account to instance config
|
// Vapid key has moved from account to instance config
|
||||||
const config = getCurrentInstanceConfiguration();
|
const config = instance
|
||||||
|
? getInstanceConfiguration(instance)
|
||||||
|
: getCurrentInstanceConfiguration();
|
||||||
const vapidKey = config?.vapid?.publicKey || config?.vapid?.public_key;
|
const vapidKey = config?.vapid?.publicKey || config?.vapid?.public_key;
|
||||||
return vapidKey || getCurrentAccount()?.vapidKey;
|
return vapidKey || getCurrentAccount()?.vapidKey;
|
||||||
}
|
}
|
||||||
|
@ -180,3 +182,16 @@ export function isMediaFirstInstance() {
|
||||||
const instance = getCurrentInstance();
|
const instance = getCurrentInstance();
|
||||||
return /pixelfed/i.test(instance?.version);
|
return /pixelfed/i.test(instance?.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CREDENTIAL_APPLICATIONS_KEY = 'credentialApplications';
|
||||||
|
|
||||||
|
export function storeCredentialApplication(instanceURL, credentialApplication) {
|
||||||
|
const stored = store.local.getJSON(CREDENTIAL_APPLICATIONS_KEY) || {};
|
||||||
|
stored[instanceURL] = credentialApplication;
|
||||||
|
store.local.setJSON(CREDENTIAL_APPLICATIONS_KEY, stored);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCredentialApplication(instanceURL) {
|
||||||
|
const stored = store.local.getJSON(CREDENTIAL_APPLICATIONS_KEY) || {};
|
||||||
|
return stored[instanceURL] || null;
|
||||||
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue