This repository has been archived by the owner on Sep 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'development' into link-pr-to-issue
- Loading branch information
Showing
8 changed files
with
1,117 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
nodeLinker: node-modules | ||
|
||
yarnPath: yarn/releases/yarn-3.5.0.cjs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { DefaultPriceConfig } from "../configs"; | ||
import { WideLabel, WideOrgConfig, WideRepoConfig } from "./private"; | ||
|
||
export const getBaseMultiplier = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): number => { | ||
if (parsedRepo && parsedRepo["baseMultiplier"] && !Number.isNaN(Number(parsedRepo["baseMultiplier"]))) { | ||
return Number(parsedRepo["baseMultiplier"]); | ||
} else if (parsedOrg && parsedOrg["baseMultiplier"] && !Number.isNaN(Number(parsedOrg["baseMultiplier"]))) { | ||
return Number(parsedOrg["baseMultiplier"]); | ||
} else { | ||
return Number(DefaultPriceConfig["baseMultiplier"]); | ||
} | ||
}; | ||
|
||
export const getTimeLabels = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): WideLabel[] => { | ||
if (parsedRepo && parsedRepo["timeLabels"] && Array.isArray(parsedRepo["timeLabels"]) && parsedRepo["timeLabels"].length > 0) { | ||
return parsedRepo["timeLabels"]; | ||
} else if (parsedOrg && parsedOrg["timeLabels"] && Array.isArray(parsedOrg["timeLabels"]) && parsedOrg["timeLabels"].length > 0) { | ||
return parsedOrg["timeLabels"]; | ||
} else { | ||
return DefaultPriceConfig["timeLabels"]; | ||
} | ||
}; | ||
|
||
export const getPriorityLabels = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): WideLabel[] => { | ||
if (parsedRepo && parsedRepo["priorityLabels"] && Array.isArray(parsedRepo["priorityLabels"]) && parsedRepo["priorityLabels"].length > 0) { | ||
return parsedRepo["priorityLabels"]; | ||
} else if (parsedOrg && parsedOrg["priorityLabels"] && Array.isArray(parsedOrg["priorityLabels"]) && parsedOrg["priorityLabels"].length > 0) { | ||
return parsedOrg["priorityLabels"]; | ||
} else { | ||
return DefaultPriceConfig["priorityLabels"]; | ||
} | ||
}; | ||
|
||
export const getAutoPayMode = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): boolean => { | ||
if (parsedRepo && parsedRepo["autoPayMode"] && typeof parsedRepo["autoPayMode"] === "boolean") { | ||
return parsedRepo["autoPayMode"]; | ||
} else if (parsedOrg && parsedOrg["autoPayMode"] && typeof parsedOrg["autoPayMode"] === "boolean") { | ||
return parsedOrg["autoPayMode"]; | ||
} else { | ||
return true; | ||
} | ||
}; | ||
|
||
export const getAnalyticsMode = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): boolean => { | ||
if (parsedRepo && parsedRepo["analyticsMode"] && typeof parsedRepo["analyticsMode"] === "boolean") { | ||
return parsedRepo["analyticsMode"]; | ||
} else if (parsedOrg && parsedOrg["analyticsMode"] && typeof parsedOrg["analyticsMode"] === "boolean") { | ||
return parsedOrg["analyticsMode"]; | ||
} else { | ||
return false; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import _sodium from "libsodium-wrappers"; | ||
import YAML from "yaml"; | ||
import { getBotConfig } from "../bindings"; | ||
import { Payload } from "../types"; | ||
import { Context } from "probot"; | ||
import { getAnalyticsMode, getAutoPayMode, getBaseMultiplier, getPriorityLabels, getTimeLabels } from "./helpers"; | ||
|
||
const CONFIG_REPO = "ubiquibot-config"; | ||
const KEY_PATH = ".github/ubiquibot-config.yml"; | ||
const KEY_NAME = "PSK"; | ||
const KEY_PREFIX = "HSK_"; | ||
|
||
export const getConfigSuperset = async (context: Context, type: "org" | "repo"): Promise<string | undefined> => { | ||
try { | ||
const payload = context.payload as Payload; | ||
const repo = type === "org" ? CONFIG_REPO : payload.repository.name!; | ||
const { data } = await context.octokit.rest.repos.getContent({ | ||
owner: payload.organization?.login!, | ||
repo: repo, | ||
path: KEY_PATH, | ||
mediaType: { | ||
format: "raw", | ||
}, | ||
}); | ||
return data as unknown as string; | ||
} catch (error: any) { | ||
return undefined; | ||
} | ||
}; | ||
|
||
export interface WideLabel { | ||
name: string; | ||
weight: number; | ||
value?: number | undefined; | ||
target: string; | ||
} | ||
|
||
export interface WideConfig { | ||
baseMultiplier?: number; | ||
timeLabels?: WideLabel[]; | ||
priorityLabels?: WideLabel[]; | ||
autoPayMode?: boolean; | ||
analyticsMode?: boolean; | ||
} | ||
|
||
export interface WideRepoConfig extends WideConfig {} | ||
|
||
export interface WideOrgConfig extends WideConfig { | ||
PSK?: string; | ||
} | ||
|
||
export interface DataConfig { | ||
privateKey: string; | ||
baseMultiplier: number; | ||
timeLabels: WideLabel[]; | ||
priorityLabels: WideLabel[]; | ||
autoPayMode: boolean; | ||
analyticsMode: boolean; | ||
} | ||
|
||
export const parseYAML = async (data: any): Promise<any | undefined> => { | ||
try { | ||
const parsedData = await YAML.parse(data); | ||
if (parsedData !== null) { | ||
return parsedData; | ||
} else { | ||
return undefined; | ||
} | ||
} catch (error) { | ||
return undefined; | ||
} | ||
}; | ||
|
||
export const getPrivateKey = async (cipherText: string): Promise<string | undefined> => { | ||
try { | ||
await _sodium.ready; | ||
const sodium = _sodium; | ||
const { | ||
sodium: { publicKey, privateKey }, | ||
} = getBotConfig(); | ||
|
||
if (publicKey === "" || privateKey === "") { | ||
return undefined; | ||
} | ||
|
||
const binPub = sodium.from_base64(publicKey, sodium.base64_variants.URLSAFE_NO_PADDING); | ||
const binPriv = sodium.from_base64(privateKey, sodium.base64_variants.URLSAFE_NO_PADDING); | ||
const binCipher = sodium.from_base64(cipherText, sodium.base64_variants.URLSAFE_NO_PADDING); | ||
|
||
let walletPrivateKey: string | undefined = sodium.crypto_box_seal_open(binCipher, binPub, binPriv, "text"); | ||
walletPrivateKey = walletPrivateKey.startsWith(KEY_PREFIX) ? walletPrivateKey.replace(KEY_PREFIX, "") : undefined; | ||
return walletPrivateKey; | ||
} catch (error: any) { | ||
return undefined; | ||
} | ||
}; | ||
|
||
export const getScalarKey = async (X25519_PRIVATE_KEY: string | undefined): Promise<string | undefined> => { | ||
try { | ||
if (X25519_PRIVATE_KEY !== undefined) { | ||
await _sodium.ready; | ||
const sodium = _sodium; | ||
|
||
const binPriv = sodium.from_base64(X25519_PRIVATE_KEY, sodium.base64_variants.URLSAFE_NO_PADDING); | ||
const scalerPub = sodium.crypto_scalarmult_base(binPriv, "base64"); | ||
return scalerPub; | ||
} | ||
return undefined; | ||
} catch (error: any) { | ||
return undefined; | ||
} | ||
}; | ||
|
||
export const getWideConfig = async (context: Context): Promise<DataConfig> => { | ||
const orgConfig = await getConfigSuperset(context, "org"); | ||
const repoConfig = await getConfigSuperset(context, "repo"); | ||
|
||
const parsedOrg: WideOrgConfig | undefined = await parseYAML(orgConfig); | ||
const parsedRepo: WideRepoConfig | undefined = await parseYAML(repoConfig); | ||
const PSK = parsedOrg && parsedOrg[KEY_NAME] ? await getPrivateKey(parsedOrg[KEY_NAME]) : undefined; | ||
|
||
const configData: DataConfig = { | ||
privateKey: PSK ?? process.env.UBIQUITY_BOT_EVM_PRIVATE_KEY ?? "", | ||
baseMultiplier: getBaseMultiplier(parsedRepo, parsedOrg), | ||
timeLabels: getTimeLabels(parsedRepo, parsedOrg), | ||
priorityLabels: getPriorityLabels(parsedRepo, parsedOrg), | ||
autoPayMode: getAutoPayMode(parsedRepo, parsedOrg), | ||
analyticsMode: getAnalyticsMode(parsedRepo, parsedOrg), | ||
}; | ||
|
||
return configData; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.