mirror of
https://github.com/ragestudio/relic.git
synced 2025-06-09 10:34:18 +00:00
merge from local
This commit is contained in:
parent
361d07d3f5
commit
87b3e3aed3
@ -24,6 +24,9 @@ export default defineConfig({
|
|||||||
// },
|
// },
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
|
server: {
|
||||||
|
port: 1040,
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"config": resolve("src/renderer/config"),
|
"config": resolve("src/renderer/config"),
|
||||||
|
@ -1,5 +1,34 @@
|
|||||||
class AuthService {
|
import { safeStorage } from "electron"
|
||||||
authorizeFromUrl(url) {
|
import sendToRender from "./utils/sendToRender"
|
||||||
console.log("authorizeFromUrl", url)
|
|
||||||
|
export default class AuthService {
|
||||||
|
authorize(pkg_id, token) {
|
||||||
|
console.log("Authorizing", pkg_id, token)
|
||||||
|
global.SettingsStore.set(`auth:${pkg_id}`, safeStorage.encryptString(token))
|
||||||
|
|
||||||
|
sendToRender(`new:notification`, {
|
||||||
|
message: "Authorized",
|
||||||
|
description: "Now you can start this package",
|
||||||
|
})
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
unauthorize(pkg_id) {
|
||||||
|
global.SettingsStore.delete(`auth:${pkg_id}`)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
getAuth(pkg_id) {
|
||||||
|
const value = global.SettingsStore.get(`auth:${pkg_id}`)
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("getAuth", value)
|
||||||
|
|
||||||
|
return safeStorage.decryptString(Buffer.from(value.data))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,6 +21,8 @@ import { readManifest } from "./utils/readManifest"
|
|||||||
|
|
||||||
import GoogleDriveAPI from "./lib/google_drive"
|
import GoogleDriveAPI from "./lib/google_drive"
|
||||||
|
|
||||||
|
import AuthService from "./auth"
|
||||||
|
|
||||||
const { autoUpdater } = require("electron-differential-updater")
|
const { autoUpdater } = require("electron-differential-updater")
|
||||||
const ProtocolRegistry = require("protocol-registry")
|
const ProtocolRegistry = require("protocol-registry")
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ class ElectronApp {
|
|||||||
this.win = null
|
this.win = null
|
||||||
}
|
}
|
||||||
|
|
||||||
authService = new AuthService()
|
authService = global.authService = new AuthService()
|
||||||
|
|
||||||
handlers = {
|
handlers = {
|
||||||
"pkg:list": async () => {
|
"pkg:list": async () => {
|
||||||
@ -69,6 +71,9 @@ class ElectronApp {
|
|||||||
"pkg:cancel_install": async (event, manifest_id) => {
|
"pkg:cancel_install": async (event, manifest_id) => {
|
||||||
return await this.pkgManager.uninstall(manifest_id)
|
return await this.pkgManager.uninstall(manifest_id)
|
||||||
},
|
},
|
||||||
|
"pkg:delete_auth": async (event, manifest_id) => {
|
||||||
|
return this.authService.unauthorize(manifest_id)
|
||||||
|
},
|
||||||
"pkg:uninstall": async (event, ...args) => {
|
"pkg:uninstall": async (event, ...args) => {
|
||||||
return await this.pkgManager.uninstall(...args)
|
return await this.pkgManager.uninstall(...args)
|
||||||
},
|
},
|
||||||
@ -99,7 +104,16 @@ class ElectronApp {
|
|||||||
return global.SettingsStore.has(key)
|
return global.SettingsStore.has(key)
|
||||||
},
|
},
|
||||||
"app:init": async (event, data) => {
|
"app:init": async (event, data) => {
|
||||||
await setup()
|
try {
|
||||||
|
await setup()
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
|
||||||
|
sendToRender("new:notification", {
|
||||||
|
message: "Setup failed",
|
||||||
|
description: err.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// check if can decode google drive token
|
// check if can decode google drive token
|
||||||
const googleDrive_enabled = !!(await GoogleDriveAPI.readCredentials())
|
const googleDrive_enabled = !!(await GoogleDriveAPI.readCredentials())
|
||||||
@ -158,20 +172,21 @@ class ElectronApp {
|
|||||||
handleURLProtocol(url) {
|
handleURLProtocol(url) {
|
||||||
const urlStarter = `${protocolRegistryNamespace}://`
|
const urlStarter = `${protocolRegistryNamespace}://`
|
||||||
|
|
||||||
|
console.log(url)
|
||||||
|
|
||||||
if (url.startsWith(urlStarter)) {
|
if (url.startsWith(urlStarter)) {
|
||||||
const urlValue = url.split(urlStarter)[1]
|
const urlValue = url.split(urlStarter)[1]
|
||||||
|
|
||||||
const explicitAction = urlValue.split("%3E")
|
const explicitAction = urlValue.split("#")
|
||||||
|
|
||||||
if (explicitAction[1]) {
|
console.log(explicitAction)
|
||||||
const [action, value] = explicitAction
|
|
||||||
|
|
||||||
switch (action) {
|
if (explicitAction[0]) {
|
||||||
case "install": {
|
switch (explicitAction[0]) {
|
||||||
return sendToRender("installation:invoked", value)
|
|
||||||
}
|
|
||||||
case "authorize": {
|
case "authorize": {
|
||||||
return authService.authorizeFromUrl(url)
|
const [pkgid, token] = explicitAction[1].split("%23")
|
||||||
|
|
||||||
|
return this.authService.authorize(pkgid, token)
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return sendToRender("new:message", {
|
return sendToRender("new:message", {
|
||||||
|
59
src/main/lib/auth/index.js
Normal file
59
src/main/lib/auth/index.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import open from "open"
|
||||||
|
import axios from "axios"
|
||||||
|
import sendToRender from "../../utils/sendToRender"
|
||||||
|
|
||||||
|
export default class Auth {
|
||||||
|
constructor(manifest) {
|
||||||
|
this.manifest = manifest
|
||||||
|
|
||||||
|
console.log(this.manifest)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get() {
|
||||||
|
const authData = global.authService.getAuth(this.manifest.id)
|
||||||
|
|
||||||
|
console.log(authData)
|
||||||
|
|
||||||
|
if (authData && this.manifest.auth && this.manifest.auth.getter) {
|
||||||
|
const result = await axios({
|
||||||
|
method: "POST",
|
||||||
|
url: this.manifest.auth.getter,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
auth_data: authData,
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
sendToRender(`new:notification`, {
|
||||||
|
type: "error",
|
||||||
|
message: "Failed to authorize",
|
||||||
|
description: err.response.data.message ?? err.response.data.error ?? err.message,
|
||||||
|
duration: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result instanceof Error) {
|
||||||
|
throw result
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(result.data)
|
||||||
|
|
||||||
|
return result.data
|
||||||
|
}
|
||||||
|
|
||||||
|
return authData
|
||||||
|
}
|
||||||
|
|
||||||
|
request() {
|
||||||
|
if (!this.manifest.auth) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const authURL = this.manifest.auth.fetcher
|
||||||
|
|
||||||
|
open(authURL)
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
import MCL from "./mcl"
|
import mcl from "./mcl"
|
||||||
import RendererIPC from "./renderer_ipc"
|
import ipc from "./renderer_ipc"
|
||||||
import rfs from "./rfs"
|
import rfs from "./rfs"
|
||||||
import exec from "./execa/public_lib"
|
import exec from "./execa/public_lib"
|
||||||
|
import auth from "./auth"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mcl: MCL,
|
mcl: mcl,
|
||||||
ipc: RendererIPC,
|
ipc: ipc,
|
||||||
rfs: rfs,
|
rfs: rfs,
|
||||||
exec: exec,
|
exec: exec,
|
||||||
|
auth: auth,
|
||||||
}
|
}
|
@ -35,9 +35,10 @@ async function main() {
|
|||||||
let sevenzip_exec = Vars.sevenzip_path
|
let sevenzip_exec = Vars.sevenzip_path
|
||||||
let git_exec = Vars.git_path
|
let git_exec = Vars.git_path
|
||||||
let rclone_exec = Vars.rclone_path
|
let rclone_exec = Vars.rclone_path
|
||||||
|
let java_exec = Vars.java_path
|
||||||
|
|
||||||
if (!fs.existsSync(sevenzip_exec)) {
|
if (!fs.existsSync(sevenzip_exec)) {
|
||||||
global.win.webContents.send("setup:step", "Downloading 7z binaries...")
|
global.win.webContents.send("setup_step", "Downloading 7z binaries...")
|
||||||
console.log(`Downloading 7z binaries...`)
|
console.log(`Downloading 7z binaries...`)
|
||||||
|
|
||||||
fs.mkdirSync(path.resolve(binariesPath, "7z-bin"), { recursive: true })
|
fs.mkdirSync(path.resolve(binariesPath, "7z-bin"), { recursive: true })
|
||||||
@ -54,16 +55,12 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(git_exec)) {
|
if (!fs.existsSync(git_exec) && process.platform === "win32") {
|
||||||
if (process.platform !== "win32") {
|
|
||||||
return git_exec = null
|
|
||||||
}
|
|
||||||
|
|
||||||
const tempPath = path.resolve(binariesPath, "git-bundle.zip")
|
const tempPath = path.resolve(binariesPath, "git-bundle.zip")
|
||||||
const binPath = path.resolve(binariesPath, "git-bin")
|
const binPath = path.resolve(binariesPath, "git-bin")
|
||||||
|
|
||||||
if (!fs.existsSync(tempPath)) {
|
if (!fs.existsSync(tempPath)) {
|
||||||
global.win.webContents.send("setup:step", "Downloading GIT binaries...")
|
global.win.webContents.send("setup_step", "Downloading GIT binaries...")
|
||||||
console.log(`Downloading git binaries...`)
|
console.log(`Downloading git binaries...`)
|
||||||
|
|
||||||
let url = resolveDestBin(`https://storage.ragestudio.net/rstudio/binaries/git`, "git-bundle-2.4.0.zip")
|
let url = resolveDestBin(`https://storage.ragestudio.net/rstudio/binaries/git`, "git-bundle-2.4.0.zip")
|
||||||
@ -74,7 +71,7 @@ async function main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
global.win.webContents.send("setup:step", "Extracting GIT binaries...")
|
global.win.webContents.send("setup_step", "Extracting GIT binaries...")
|
||||||
console.log(`Extracting GIT...`)
|
console.log(`Extracting GIT...`)
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
@ -84,9 +81,9 @@ async function main() {
|
|||||||
fs.unlinkSync(tempPath)
|
fs.unlinkSync(tempPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(Vars.rclone_path)) {
|
if (!fs.existsSync(Vars.rclone_path) && process.platform === "win32") {
|
||||||
console.log(`Downloading rclone binaries...`)
|
console.log(`Downloading rclone binaries...`)
|
||||||
global.win.webContents.send("setup:step", "Downloading rclone binaries...")
|
global.win.webContents.send("setup_step", "Downloading rclone binaries...")
|
||||||
|
|
||||||
const tempPath = path.resolve(binariesPath, "rclone-bin.zip")
|
const tempPath = path.resolve(binariesPath, "rclone-bin.zip")
|
||||||
|
|
||||||
@ -97,7 +94,7 @@ async function main() {
|
|||||||
fs.createWriteStream(tempPath)
|
fs.createWriteStream(tempPath)
|
||||||
)
|
)
|
||||||
|
|
||||||
global.win.webContents.send("setup:step", "Extracting rclone binaries...")
|
global.win.webContents.send("setup_step", "Extracting rclone binaries...")
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
fs.createReadStream(tempPath).pipe(unzipper.Extract({ path: path.resolve(binariesPath, "rclone-bin") })).on("close", resolve).on("error", reject)
|
fs.createReadStream(tempPath).pipe(unzipper.Extract({ path: path.resolve(binariesPath, "rclone-bin") })).on("close", resolve).on("error", reject)
|
||||||
@ -112,7 +109,7 @@ async function main() {
|
|||||||
|
|
||||||
if (!fs.existsSync(Vars.java_path)) {
|
if (!fs.existsSync(Vars.java_path)) {
|
||||||
console.log(`Downloading java binaries...`)
|
console.log(`Downloading java binaries...`)
|
||||||
global.win.webContents.send("setup:step", "Downloading Java JDK...")
|
global.win.webContents.send("setup_step", "Downloading Java JDK...")
|
||||||
|
|
||||||
const tempPath = path.resolve(binariesPath, "java-jdk.zip")
|
const tempPath = path.resolve(binariesPath, "java-jdk.zip")
|
||||||
|
|
||||||
@ -123,14 +120,14 @@ async function main() {
|
|||||||
fs.createWriteStream(tempPath)
|
fs.createWriteStream(tempPath)
|
||||||
)
|
)
|
||||||
|
|
||||||
global.win.webContents.send("setup:step", "Extracting JAVA...")
|
global.win.webContents.send("setup_step", "Extracting JAVA...")
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
fs.createReadStream(tempPath).pipe(unzipper.Extract({ path: path.resolve(binariesPath, "java-jdk") })).on("close", resolve).on("error", reject)
|
fs.createReadStream(tempPath).pipe(unzipper.Extract({ path: path.resolve(binariesPath, "java-jdk") })).on("close", resolve).on("error", reject)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (os.platform() !== "win32") {
|
if (os.platform() !== "win32") {
|
||||||
ChildProcess.execSync("chmod +x " + Vars.rclone_path)
|
ChildProcess.execSync("chmod +x " + path.resolve(binariesPath, "java-jdk"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.unlinkSync(tempPath)
|
fs.unlinkSync(tempPath)
|
||||||
@ -141,7 +138,7 @@ async function main() {
|
|||||||
console.log(`rclone binaries: ${rclone_exec}`)
|
console.log(`rclone binaries: ${rclone_exec}`)
|
||||||
console.log(`JAVA jdk: ${Vars.java_path}`)
|
console.log(`JAVA jdk: ${Vars.java_path}`)
|
||||||
|
|
||||||
global.win.webContents.send("setup:step", undefined)
|
global.win.webContents.send("setup_step", undefined)
|
||||||
global.win.webContents.send("setup:done")
|
global.win.webContents.send("setup:done")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ export default async (manifest = {}) => {
|
|||||||
id: manifest.id,
|
id: manifest.id,
|
||||||
version: manifest.version,
|
version: manifest.version,
|
||||||
install_path: install_path,
|
install_path: install_path,
|
||||||
|
auth: manifest.auth,
|
||||||
|
configs: manifest.configs,
|
||||||
|
os_string: os_string,
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(`[${manifest.id}] initManifest() | Using libraries: ${manifest.import_libs.join(", ")}`)
|
console.log(`[${manifest.id}] initManifest() | Using libraries: ${manifest.import_libs.join(", ")}`)
|
||||||
|
@ -21,6 +21,7 @@ class App extends React.Component {
|
|||||||
pkg: null,
|
pkg: null,
|
||||||
initializing: false,
|
initializing: false,
|
||||||
|
|
||||||
|
setup_step: null,
|
||||||
updateAvailable: false,
|
updateAvailable: false,
|
||||||
updateText: null,
|
updateText: null,
|
||||||
|
|
||||||
@ -99,7 +100,9 @@ class App extends React.Component {
|
|||||||
|
|
||||||
message.success("Google Drive API unauthorized")
|
message.success("Google Drive API unauthorized")
|
||||||
},
|
},
|
||||||
"setup:step": (event, data) => {
|
"setup_step": (event, data) => {
|
||||||
|
console.log(`setup:step`, data)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
setup_step: data,
|
setup_step: data,
|
||||||
})
|
})
|
||||||
|
@ -115,6 +115,24 @@ const PackageOptions = (props) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDeleteAuth() {
|
||||||
|
antd.Modal.confirm({
|
||||||
|
title: "Clear auth data",
|
||||||
|
content: "Are you sure you want to delete auth data? May you need to reauthorize.",
|
||||||
|
onOk() {
|
||||||
|
const closeModal = props.onClose || props.close
|
||||||
|
|
||||||
|
if (closeModal) {
|
||||||
|
closeModal()
|
||||||
|
} else {
|
||||||
|
app.location.push("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc.exec("pkg:delete_auth", manifest.id)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function canApplyChanges() {
|
function canApplyChanges() {
|
||||||
return Object.keys(changes).length > 0
|
return Object.keys(changes).length > 0
|
||||||
}
|
}
|
||||||
@ -223,6 +241,17 @@ const PackageOptions = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="package_options-actions">
|
<div className="package_options-actions">
|
||||||
|
{
|
||||||
|
manifest.auth && <antd.Button
|
||||||
|
onClick={handleDeleteAuth}
|
||||||
|
type="default"
|
||||||
|
size="small"
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
Delete auth
|
||||||
|
</antd.Button>
|
||||||
|
}
|
||||||
|
|
||||||
<antd.Button
|
<antd.Button
|
||||||
onClick={handleReinstall}
|
onClick={handleReinstall}
|
||||||
icon={<Icons.MdReplay />}
|
icon={<Icons.MdReplay />}
|
||||||
|
@ -155,7 +155,7 @@ export const PageRender = (props) => {
|
|||||||
|
|
||||||
const globalState = React.useContext(GlobalStateContext)
|
const globalState = React.useContext(GlobalStateContext)
|
||||||
|
|
||||||
if (globalState.setup_step && globalState.loading) {
|
if (globalState.setup_step || globalState.loading) {
|
||||||
return <div className="app_setup">
|
return <div className="app_setup">
|
||||||
<BarLoader
|
<BarLoader
|
||||||
className="app_loader"
|
className="app_loader"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user