Skip to content

Commit

Permalink
mv3 migration related UX changes
Browse files Browse the repository at this point in the history
  • Loading branch information
imolorhe committed Jul 1, 2024
1 parent 3da4b2d commit 678a616
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 28 deletions.
2 changes: 1 addition & 1 deletion bin/dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ cd "$ROOT"
yarn

# stripe login (if API key is expired)
npx concurrently --kill-others "yarn start:app" "yarn start:api:dev" "yarn start:redirect" "yarn start:stripe:listen" --names app,api,redirect,stripe
npx concurrently --kill-others "yarn start:app" "yarn start:api:dev" "yarn start:redirect" "yarn start:sandbox" "yarn start:stripe:listen" --names app,api,redirect,sandbox,stripe
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"start:api:prod": "yarn --cwd packages/altair-db prisma migrate deploy && yarn --cwd packages/altair-db prisma db seed && yarn --cwd packages/altair-api start:prod",
"start:app": "nx start @altairgraphql/app",
"start:redirect": "nx dev @altairgraphql/login-redirect",
"start:sandbox": "nx dev @altairgraphql/iframe-sandbox",
"start:electron": "nx dev altair",
"start:stripe:listen": "stripe listen --forward-to http://localhost:3000/stripe-webhook",
"test": "nx run-many --target=test --all",
Expand Down
4 changes: 1 addition & 3 deletions packages/altair-app/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
"tsConfig": "src/tsconfig.app.json",
"polyfills": "src/polyfills.ts",
"assets": ["src/assets", "src/favicon.ico"],
"styles": [
"src/styles.scss"
],
"styles": ["src/styles.scss"],
"stylePreprocessorOptions": {
"includePaths": ["node_modules"]
},
Expand Down
7 changes: 4 additions & 3 deletions packages/altair-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@altairgraphql/app",
"description": "Contains the altair app",
"version": "7.2.1",
"author": "Samuel Imolorhe <[email protected]> (https://sirmuel.design/)",
"author": "Samuel Imolorhe <[email protected]> (https://altairgraphql.dev/)",
"dependencies": {
"@altairgraphql/api-utils": "^7.2.1",
"@altairgraphql/db": "^7.2.1",
Expand Down Expand Up @@ -176,11 +176,12 @@
"scripts": {
"analyze": "ng build --stats-json && npx webpack-bundle-analyzer dist/stats.json",
"analyze:prod": "ng build --aot --stats-json && npx webpack-bundle-analyzer dist/stats.json",
"build": "node --max_old_space_size=8000 ../../node_modules/@angular/cli/bin/ng build --aot --stats-json && yarn sentry:sourcemaps:inject",
"ng:build": "node --max_old_space_size=8000 ../../node_modules/@angular/cli/bin/ng build --aot --stats-json --output-hashing=none",
"build": "yarn ng:build && yarn sentry:sourcemaps:inject",
"lint": "ng lint",
"new:component": "ng g component modules/altair/components/",
"ng": "ng",
"prepare": "node --max_old_space_size=8000 ../../node_modules/@angular/cli/bin/ng build --output-hashing=none --aot --stats-json && yarn sentry:sourcemaps:inject",
"prepare": "yarn build",
"start": "ng serve",
"sentry:sourcemaps:inject": "sentry-cli sourcemaps inject --org altair-graphql --project electron ./dist",
"test": "jest && ng lint",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@
Do you find this app useful? Would you mind supporting its development?
</span>
<button
class="btn alert-action"
class="btn btn--primary btn--light"
(click)="openDonationPage($event)"
track-id="donate"
>
Expand All @@ -468,7 +468,7 @@
@if ((account$ | async)?.plan?.canUpgradePro) {
or
<button
class="btn alert-action"
class="btn btn--primary btn--light"
(click)="setShowUpgradeDialog(true)"
track-id="upgrade_pro"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,15 @@ export class PluginRegistryService {
const plugin = createV1Plugin(name, manifest);
this.addV1Plugin(name, plugin);
debug.log('PLUGIN', 'V1 plugin scripts and styles injected and loaded.');
this.notifyService.warning(
`V1 plugins are deprecated and will be disabled in the future. If you're an owner of ${name}, consider migrating to V3.`,
undefined,
{
data: {
url: 'https://altairgraphql.dev/docs/learn/mv3',
},
}
);

return plugin;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ import { getClientConfig } from '@altairgraphql/api-utils';
import { debug } from '../../utils/logger';
import { environment } from 'environments/environment';
import { EvaluatorWorkerClient } from './evaluator-worker-client';
import { isExtension } from '../../utils';

export class EvaluatorFrameClient extends ScriptEvaluatorClient {
private config = getClientConfig(
environment.production ? 'production' : 'development'
);
private iframe = this.createIframe();

constructor(private sandboxUrl: string) {
super();
}

private createIframe() {
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
const sandboxUrl = new URL(this.config.sandboxUrl);
const sandboxUrl = new URL(this.sandboxUrl);
sandboxUrl.searchParams.set('sc', window.location.origin);
sandboxUrl.searchParams.set('action', 'evaluator');
iframe.src = sandboxUrl.toString();
Expand All @@ -34,7 +36,7 @@ export class EvaluatorFrameClient extends ScriptEvaluatorClient {
handler: (type: T, e: ScriptEventData<T>) => void
): void {
window.addEventListener('message', (e: MessageEvent<ScriptEventData<T>>) => {
if (e.origin !== new URL(this.config.sandboxUrl).origin) {
if (e.origin !== new URL(this.sandboxUrl).origin) {
return;
}
const event = e.data;
Expand All @@ -48,10 +50,7 @@ export class EvaluatorFrameClient extends ScriptEvaluatorClient {
}
send(type: string, payload: any): void {
this.iframe.addEventListener('load', () => {
this.iframe.contentWindow?.postMessage(
{ type, payload },
this.config.sandboxUrl
);
this.iframe.contentWindow?.postMessage({ type, payload }, this.sandboxUrl);
});
}
onError(handler: (err: any) => void): void {
Expand All @@ -63,10 +62,19 @@ export class EvaluatorFrameClient extends ScriptEvaluatorClient {
}

export class EvaluatorClientFactory implements ScriptEvaluatorClientFactory {
create() {
if (document.baseURI && new URL(document.baseURI).origin === window.origin) {
async create() {
// If the current window is the same origin as the baseURI (except for mv3 extension), then use the worker client
if (
document.baseURI &&
new URL(document.baseURI).origin === window.origin &&
// don't use worker client for manifest v3 extensions, as they don't support unsafe-eval even in web workers
!(isExtension && chrome.runtime.getManifest().manifest_version === 3)
) {
return new EvaluatorWorkerClient();
}
return new EvaluatorFrameClient();
const config = getClientConfig(
environment.production ? 'production' : 'development'
);
return new EvaluatorFrameClient(config.sandboxUrl);
}
}
5 changes: 0 additions & 5 deletions packages/altair-app/src/scss/components/_alert.scss
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ nz-alert {
text-align: center;
}

.alert-action {
border: currentColor 1px solid;
border-radius: 4px;
}

:root {
--hot-toast-color: var(--theme-font-color);
--hot-toast-bg: var(--theme-bg-color);
Expand Down
2 changes: 1 addition & 1 deletion packages/altair-core/src/script/evaluator-client-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class ScriptEvaluatorClientEngine {
) {}

private async getClient() {
const client = this.client ?? this.engineFactory.create();
const client = this.client ?? (await this.engineFactory.create());
this.client = client;
return client;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/altair-core/src/script/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export interface ScriptWorkerMessageData {
}

export interface ScriptEvaluatorClientFactory {
create: () => ScriptEvaluatorClient;
create: () => Promise<ScriptEvaluatorClient>;
}
export abstract class ScriptEvaluatorClient {
abstract subscribe<T extends ScriptEvent>(
Expand Down
24 changes: 24 additions & 0 deletions packages/altair-docs/docs/learn/mv3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
---

# Migrating Altair Browser Extensions to Manifest v3

Altair GraphQL Client comes in various [forms and variants](/docs/features/multiple-platforms) to meet developers where they are. This allows developers use Altair in the way that best suits their workflow. One of the popular ways Altair is used is as a browser extension made available on all the major browsers. This allows developers to interact with their GraphQL APIs from their browser without having to leave the browser, or install an additional application directly on their device. The browser extension also allows developers interact with their cookie authenticated APIs, which reduces the toil of needing a different authentication mechanism from their web app.

The browser extension is built using the Chrome extension API, which has been around for a while and has been the standard for building browser extensions. However, the Chrome extension API has been evolving and the latest version is the [manifest v3](https://blog.chromium.org/2020/12/manifest-v3-now-available-on-m88-beta.html). The manifest v3 is a new version of the Chrome extension API that introduces a number of changes to the way extensions are built and how they interact with the browser. This new version of the API is designed to improve the performance and security of extensions, and to make it easier for developers to build and maintain their extensions. This crackdown on extension security also brought tighter restrictions on the way extensions interact with the browser and the web pages, which also has implications for the Altair browser extensions.

The chrome team has [announced](https://developer.chrome.com/docs/extensions/develop/migrate/mv2-deprecation-timeline) that the manifest v2 will be deprecated later in 2024, and all extensions will be required to migrate to manifest v3. This means that the Altair browser extension will need to be updated to support manifest v3 in order to continue working on the latest versions of Chrome and other browsers that support the manifest v3 API. We [investigated](https://github.com/altair-graphql/altair/issues/2504) the impact on the Altair browser extension and found that there are a number of changes required to support manifest v3.

## Plugins

The biggest impact for Altair is for [plugins](/docs/plugins/). Manifest version 3 removes the ability to execute remotely hosted code, which is how Altair v1 plugins are currently implemented. This means that the current Altair v1 plugins will **not work** with manifest v3. We have implemented a [new plugin system](/docs/plugins/writing-plugin#v3-plugins) for Altair that leverages the use of iframes with strictly defined communication protocols to allow plugins to run in a secure and isolated environment. This new plugin system is designed to be more secure and more performant than the current system, and to provide a better experience for developers who want to extend Altair with custom functionality, while being compatible with manifest v3.

::: tip
It is recommended that developers who have built plugins for Altair migrate their plugins to the new plugin system in order to continue using them with the latest versions of Altair. We have provided [guidance](/docs/plugins/writing-plugin#supporting-both-v2-and-v3-plugin-formats) on how to smoothen out the transition from the old and new plugin formats.
:::

In the near future, v1 plugins will still be supported in the other platforms like the desktop apps, but the browser extension will only support the new plugin system. However, we will eventually phase out the v1 plugin system in all platforms in order to maintain a consistent experience across all platforms.

## Pre-request scripts

Manifest v3 also has implications for the way pre-request scripts are executed in Altair. Pre-request scripts use `eval` in a local web worker for safe execution of the scripts. However, manifest v3 restricts the use of `eval` (except in sandboxed pages) which means that the current implementation of pre-request scripts will not work with manifest v3. Altair also executes the scripts in a sandboxed iframe whenever the web worker can't be used (e.g. when using Altair from the CDNs). This is a fallback mechanism that will continue to work with manifest v3, but requires an active internet connection to work.

0 comments on commit 678a616

Please sign in to comment.