Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add accountId to spec during runtime #10

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
Empty file modified src/index.ts
100644 → 100755
Empty file.
14 changes: 7 additions & 7 deletions src/services/plugin-service.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { BASE_URL } from '../config/constants';
import { authenticateOrCreateKey, getAuthentication } from './signer-service';
import type { KeySignMessageParams } from '../utils/verify-msg-utils';
import { getAuthentication, getSignedMessage } from './signer-service';

export async function registerPlugin(pluginId: string, accountId: string | undefined): Promise<string | null> {
const message = await authenticateOrCreateKey(accountId)
export async function registerPlugin(pluginId: string, bitteKey?: string): Promise<string | null> {

if(!message){
console.error("Failed to register plugin: Authentication failed. Try again.")
return null
if (!bitteKey) {
const signedMessage = await getSignedMessage();
bitteKey = JSON.stringify(signedMessage);
}

try {
const response = await fetch(`${BASE_URL}/${pluginId}`, { method: 'POST', headers: { 'bitte-api-key': message }});
const response = await fetch(`${BASE_URL}/${pluginId}`, { method: 'POST', headers: { 'bitte-api-key': bitteKey } });
if (response.ok) {
await response.json();
console.log(`Plugin registered successfully`);
Expand Down
27 changes: 9 additions & 18 deletions src/services/signer-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ dotenv.config({ path: `.env.local`, override: true });

/**
* Checks if there is a BITTE_KEY in the environment, verifies it, and returns the signed message.
* If no accountId is given, no verification is made and the signed message (if created) is returned.
* @returns {Promise<string | null>} A promise that resolves to the signed message if authenticated, null otherwise.
*/
export async function getAuthentication(
accountId: string | undefined
accountId?: string
): Promise<string | null> {
const bitteKeyString = process.env.BITTE_KEY;
if (!bitteKeyString) return null;

const parsedKey = JSON.parse(bitteKeyString) as KeySignMessageParams;
if (accountId && (await verifyMessage(parsedKey, accountId))) {
if (accountId && (await verifyMessage(parsedKey, accountId)) || !accountId) {
return bitteKeyString;
}

Expand All @@ -37,25 +38,17 @@ export async function getAuthentication(
/**
* Checks if there is a BITTE_KEY in the environment. If not, redirects to Bitte wallet
* for message signing and stores the signed message as an environment variable.
* @param {string | undefined} accountId - The account ID to be verified in the message, if provided.
* @returns {Promise<string | null>} A promise that resolves to the signed message if authenticated or key created, null otherwise.
*/
export async function authenticateOrCreateKey(
accountId: string | undefined
): Promise<string | null> {
const authentication = await getAuthentication(accountId);
export async function authenticateOrCreateKey(): Promise<string | null> {
const authentication = await getAuthentication();
if (authentication) {
console.log("Already authenticated.");
return authentication;
}

if (!accountId) {
console.log("Account ID is required for authentication.");
return null;
}

console.log("Not authenticated. Redirecting to Bitte wallet for signing...");
const newKey = await createAndStoreKey(accountId);
const newKey = await createAndStoreKey();
if (newKey) {
console.log("New key created and stored successfully.");
return JSON.stringify(newKey);
Expand All @@ -65,17 +58,15 @@ export async function authenticateOrCreateKey(
}
}

async function createAndStoreKey(
accountId: string
): Promise<KeySignMessageParams | null> {
async function createAndStoreKey(): Promise<KeySignMessageParams | null> {
try {
const signedMessage = await getSignedMessage();
if (!signedMessage) {
console.error("Failed to get signed message");
return null;
}

const isVerified = await verifyMessage(signedMessage, accountId);
const isVerified = await verifyMessage(signedMessage);
if (!isVerified) {
console.warn("Message verification failed");
}
Expand All @@ -88,7 +79,7 @@ async function createAndStoreKey(
}
}

function getSignedMessage(): Promise<KeySignMessageParams> {
export function getSignedMessage(): Promise<KeySignMessageParams> {
return new Promise((resolve, reject) => {
const server = createServer(handleRequest);

Expand Down
16 changes: 11 additions & 5 deletions src/services/tunnel-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { join, relative } from 'path';
import { PLAYGROUND_URL } from '../config/constants';
import { validateAndParseOpenApiSpec } from './openapi-service';
import { deletePlugin, registerPlugin, updatePlugin } from './plugin-service';
import { getAuthentication } from './signer-service';
import { authenticateOrCreateKey, getAuthentication } from './signer-service';
import { getSpecUrl } from '../utils/url-utils';
const BITTE_CONFIG_PATH = join(process.cwd(), 'bitte.dev.json');

Expand Down Expand Up @@ -39,7 +39,7 @@ export async function watchForChanges(pluginId: string, tunnelUrl: string): Prom
const authentication = await getAuthentication(accountId);
const result = authentication
? await updatePlugin(pluginId, accountId)
: await registerPlugin(pluginId, accountId);
: await registerPlugin(pluginId);

if (result && !authentication) {
await openPlayground(result);
Expand All @@ -64,9 +64,15 @@ async function setupAndValidate(tunnelUrl: string, pluginId: string): Promise<vo

await new Promise(resolve => setTimeout(resolve, 1000));

const specUrl = getSpecUrl(tunnelUrl)
const signedMessage = await authenticateOrCreateKey();
if (!signedMessage) {
console.log("Failed to authenticate or create a key.");
return;
}

const specUrl = getSpecUrl(tunnelUrl);

console.log("Validating OpenAPI spec...")
console.log("Validating OpenAPI spec...");
const { isValid, accountId } = await validateAndParseOpenApiSpec(specUrl);

if (!isValid) {
Expand All @@ -79,7 +85,7 @@ async function setupAndValidate(tunnelUrl: string, pluginId: string): Promise<vo
return;
}

const result = await registerPlugin(pluginId, accountId);
const result = await registerPlugin(pluginId, signedMessage);

if (!result) {
console.log('Initial registration failed. Waiting for file changes to retry...');
Expand Down
4 changes: 2 additions & 2 deletions src/utils/verify-msg-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface KeySignMessageParams {

export const verifyMessage = async (
params: KeySignMessageParams,
accountIdToVerify: string
accountIdToVerify?: string
) => {
const {
message,
Expand All @@ -26,7 +26,7 @@ export const verifyMessage = async (
accountId,
} = params;

if (accountIdToVerify !== accountId) {
if (accountIdToVerify && accountIdToVerify !== accountId) {
console.error(
`Account mismatch: signed message has account ${accountId}, but provided account was ${accountIdToVerify}`
);
Expand Down