mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-08 17:09:07 +08:00
add cookie assistant, and the fill cookie field logic of collecting cookie after login
This commit is contained in:
@@ -19,6 +19,10 @@ import JSON5 from 'json5'
|
|||||||
import url from 'url';
|
import url from 'url';
|
||||||
import packageJson from './package.json' assert {type: 'json'}
|
import packageJson from './package.json' assert {type: 'json'}
|
||||||
|
|
||||||
|
import { EventEmitter } from 'node:events'
|
||||||
|
|
||||||
|
export const loginEventBus = new EventEmitter()
|
||||||
|
|
||||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
||||||
const isRunFromUi = Boolean(process.env.MAIN_BOSSGEEKGO_UI_RUN_MODE)
|
const isRunFromUi = Boolean(process.env.MAIN_BOSSGEEKGO_UI_RUN_MODE)
|
||||||
const isUiDev = process.env.NODE_ENV === 'development'
|
const isUiDev = process.env.NODE_ENV === 'development'
|
||||||
@@ -98,7 +102,7 @@ export async function main() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const { dispose: disposeNavigation } = await blockNavigation(page, (req) => !req.url().startsWith('https://www.zhipin.com'))
|
const { dispose: disposeNavigationLock } = await blockNavigation(page, (req) => !req.url().startsWith('https://www.zhipin.com'))
|
||||||
await page.goto('https://www.zhipin.com/web/user/');
|
await page.goto('https://www.zhipin.com/web/user/');
|
||||||
|
|
||||||
const loginSuccessPromiseList = [
|
const loginSuccessPromiseList = [
|
||||||
@@ -138,8 +142,19 @@ export async function main() {
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
}).then(async () => {
|
}).then(async () => {
|
||||||
|
if (
|
||||||
|
page.url().startsWith('https://www.zhipin.com/web/common/security-check.html')
|
||||||
|
) {
|
||||||
|
await page.waitForNavigation({
|
||||||
|
timeout: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
await sleep(2000)
|
await sleep(2000)
|
||||||
const cookies = await page.cookies()
|
const cookies = await page.cookies()
|
||||||
|
loginEventBus.emit(
|
||||||
|
'cookie-collected',
|
||||||
|
cookies
|
||||||
|
)
|
||||||
return writeStorageFile('boss-cookies.json', cookies)
|
return writeStorageFile('boss-cookies.json', cookies)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { app } from 'electron'
|
import { app } from 'electron'
|
||||||
import { main } from '@geekgeekrun/launch-bosszhipin-login-page-with-preload-extension'
|
import { main, loginEventBus } from '@geekgeekrun/launch-bosszhipin-login-page-with-preload-extension'
|
||||||
import { pipeWriteRegardlessError } from './utils/pipe'
|
import { pipeWriteRegardlessError } from './utils/pipe'
|
||||||
|
import fs from "node:fs";
|
||||||
|
|
||||||
export enum DOWNLOAD_ERROR_EXIT_CODE {
|
export enum DOWNLOAD_ERROR_EXIT_CODE {
|
||||||
NO_ERROR = 0,
|
NO_ERROR = 0,
|
||||||
@@ -37,5 +38,14 @@ export const launchBossZhipinLoginPageWithPreloadExtension = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loginEventBus.once('cookie-collected', (cookies) => {
|
||||||
|
pipeWriteRegardlessError(
|
||||||
|
pipe,
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'BOSS_ZHIPIN_COOKIE_COLLECTED',
|
||||||
|
cookies
|
||||||
|
}) + '\r\n'
|
||||||
|
)
|
||||||
|
})
|
||||||
main()
|
main()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ export function createMainWindow(): void {
|
|||||||
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
|
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipcMain.on('open-external-link', (_, link) => {
|
||||||
|
shell.openExternal(link, {
|
||||||
|
activate: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
ipcMain.handle('fetch-config-file-content', async () => {
|
ipcMain.handle('fetch-config-file-content', async () => {
|
||||||
const configFileContentList = configFileNameList.map((fileName) => {
|
const configFileContentList = configFileNameList.map((fileName) => {
|
||||||
return readConfigFile(fileName)
|
return readConfigFile(fileName)
|
||||||
@@ -210,11 +216,6 @@ export function createMainWindow(): void {
|
|||||||
mainWindow?.webContents.send('geek-auto-start-chat-with-boss-stopping')
|
mainWindow?.webContents.send('geek-auto-start-chat-with-boss-stopping')
|
||||||
subProcessOfPuppeteer?.kill('SIGINT')
|
subProcessOfPuppeteer?.kill('SIGINT')
|
||||||
})
|
})
|
||||||
ipcMain.on('open-project-homepage-on-github', () => {
|
|
||||||
shell.openExternal(`https://github.com/geekgeekrun`, {
|
|
||||||
activate: true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
let subProcessOfBossZhipinLoginPageWithPreloadExtension: ChildProcess | null = null
|
let subProcessOfBossZhipinLoginPageWithPreloadExtension: ChildProcess | null = null
|
||||||
ipcMain.on('launch-bosszhipin-login-page-with-preload-extension', async () => {
|
ipcMain.on('launch-bosszhipin-login-page-with-preload-extension', async () => {
|
||||||
@@ -234,6 +235,21 @@ export function createMainWindow(): void {
|
|||||||
stdio: [null, null, null, 'pipe', 'ipc']
|
stdio: [null, null, null, 'pipe', 'ipc']
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension!.stdio[3]!.pipe(JSONStream.parse()).on(
|
||||||
|
'data',
|
||||||
|
(raw) => {
|
||||||
|
const data = raw
|
||||||
|
switch (data.type) {
|
||||||
|
case 'BOSS_ZHIPIN_COOKIE_COLLECTED': {
|
||||||
|
mainWindow?.webContents.send(data.type, data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension!.once('exit', () => {
|
subProcessOfBossZhipinLoginPageWithPreloadExtension!.once('exit', () => {
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension = null
|
subProcessOfBossZhipinLoginPageWithPreloadExtension = null
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-bind="$attrs" :close-on-click-modal="false" title="Boss直聘 Cookie助手" :width="600">
|
||||||
|
<el-alert type="warning" title="需要获取您的Boss直聘Cookie才能继续">
|
||||||
|
由于您是首次使用本程序,或者您之前使用的Boss直聘账号登录状态失效,因此您需要重新获取登录凭证。
|
||||||
|
</el-alert>
|
||||||
|
<div ml1em mt1em>
|
||||||
|
如果您了解Cookie如何获取Cookie:请打开您已登录过Boss直聘的浏览器,使用
|
||||||
|
<a
|
||||||
|
color-blue
|
||||||
|
decoration-none
|
||||||
|
href="javascript:void(0)"
|
||||||
|
@click.prevent="handleEditThisCookieExtensionStoreLinkClick"
|
||||||
|
>EditThisCookie 扩展程序/插件</a
|
||||||
|
>
|
||||||
|
进行复制,然后粘贴在下方输入框中。<br />
|
||||||
|
格式为被序列化为JSON的数组,不含两侧引号。
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div ml1em>如果您不了解相关概念,请按照以下步骤进行操作:</div>
|
||||||
|
<ol lh-2em mt-0>
|
||||||
|
<li>
|
||||||
|
<el-button size="small" type="primary" font-size-inherit @click="handleClickLaunchLogin"
|
||||||
|
>点击此处</el-button
|
||||||
|
>
|
||||||
|
启动浏览器
|
||||||
|
</li>
|
||||||
|
<li>按照正常流程,通过 <b>短信验证码/二维码/微信小程序</b> 登录您的Boss直聘账号</li>
|
||||||
|
<li>
|
||||||
|
如果流程顺利,登录后预计5-10秒内,您将可以在下方输入框看到您的Cookie
|
||||||
|
<div>
|
||||||
|
<details>
|
||||||
|
<summary color-orange cursor-pointer>我已完成登录,但Cookie一直没出现?</summary>
|
||||||
|
<div ml-2em>
|
||||||
|
如果您确实已经在浏览器中看到您已登录了Boss直聘,请尝试按照如图所示方式复制Cookie:
|
||||||
|
<figure></figure>
|
||||||
|
然后粘贴您刚刚复制的内容到下方输入框。粘贴后,将
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<el-input
|
||||||
|
v-model="collectedCookies"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{
|
||||||
|
minRows: 4,
|
||||||
|
maxRows: 10
|
||||||
|
}"
|
||||||
|
font-size-12px
|
||||||
|
></el-input>
|
||||||
|
<el-alert v-if="!collectedCookies" :closable="false">正在等待登录……</el-alert>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onUnmounted, onMounted } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
dispose: Function
|
||||||
|
})
|
||||||
|
|
||||||
|
const collectedCookies = ref('')
|
||||||
|
|
||||||
|
const handleCookieCollected = (_, payload) => {
|
||||||
|
collectedCookies.value = JSON.stringify(payload.cookies, null, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClickLaunchLogin = () => {
|
||||||
|
electron.ipcRenderer.send('launch-bosszhipin-login-page-with-preload-extension')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEditThisCookieExtensionStoreLinkClick = () => {
|
||||||
|
electron.ipcRenderer.send(
|
||||||
|
'open-external-link',
|
||||||
|
'https://chromewebstore.google.com/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
electron.ipcRenderer.once('BOSS_ZHIPIN_COOKIE_COLLECTED', handleCookieCollected)
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
electron.ipcRenderer.removeListener('BOSS_ZHIPIN_COOKIE_COLLECTED', handleCookieCollected)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import WaitForLogin from './index.vue'
|
||||||
|
|
||||||
|
export const mountGlobalDialog = () => {
|
||||||
|
const containerElId = `elForWaitForLogin`
|
||||||
|
|
||||||
|
if (document.getElementById(containerElId)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let containerEl: null | HTMLElement = (() => {
|
||||||
|
const el = document.createElement('div')
|
||||||
|
el.id = containerElId
|
||||||
|
return el
|
||||||
|
})()
|
||||||
|
document.body.append(containerEl)
|
||||||
|
|
||||||
|
const dispose = () => {
|
||||||
|
app?.unmount()
|
||||||
|
containerEl?.remove()
|
||||||
|
|
||||||
|
app = null
|
||||||
|
containerEl = null
|
||||||
|
}
|
||||||
|
let app: null | ReturnType<typeof createApp> = createApp(WaitForLogin, {
|
||||||
|
modelValue: true,
|
||||||
|
onClosed() {
|
||||||
|
dispose()
|
||||||
|
},
|
||||||
|
dispose,
|
||||||
|
}).use(ElementPlus)
|
||||||
|
app.mount(containerEl)
|
||||||
|
|
||||||
|
return {
|
||||||
|
dispose
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,10 +10,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- <div>操作过程中,本程序缓存的 Boss直聘 Cookie 会被自动更新</div> -->
|
<!-- <div>操作过程中,本程序缓存的 Boss直聘 Cookie 会被自动更新</div> -->
|
||||||
<div>
|
<div>
|
||||||
您可
|
如果您不清楚如何操作您可
|
||||||
<el-button size="small" type="primary" font-size-inherit @click="launchLogin"
|
<el-button size="small" type="primary" font-size-inherit @click="handleClickLaunchLogin"
|
||||||
>点击此处打开BOSS直聘登录页</el-button
|
>点击此处打开BOSS直聘 Cookie助手</el-button
|
||||||
>,按照稍后的提示,使用EditThisCookie复制Cookie,并进行粘贴
|
>来帮您填写。
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-input
|
<el-input
|
||||||
@@ -47,6 +47,7 @@ import JSON5 from 'json5'
|
|||||||
import { ElForm, ElMessage } from 'element-plus'
|
import { ElForm, ElMessage } from 'element-plus'
|
||||||
import router from '../../router/index'
|
import router from '../../router/index'
|
||||||
import { mountGlobalDialog as mountDependenciesSetupProgressIndicatorDialog } from '@renderer/features/DependenciesSetupProgressIndicatorDialog/operations'
|
import { mountGlobalDialog as mountDependenciesSetupProgressIndicatorDialog } from '@renderer/features/DependenciesSetupProgressIndicatorDialog/operations'
|
||||||
|
import { mountGlobalDialog as mountWaitForLoginDialog } from '@renderer/features/WaitForLoginDialog/operations'
|
||||||
|
|
||||||
const formContent = ref({
|
const formContent = ref({
|
||||||
bossZhipinCookies: '',
|
bossZhipinCookies: '',
|
||||||
@@ -128,8 +129,8 @@ const handleExpectCompaniesInputBlur = (event) => {
|
|||||||
.join(',')
|
.join(',')
|
||||||
}
|
}
|
||||||
|
|
||||||
const launchLogin = () => {
|
const handleClickLaunchLogin = () => {
|
||||||
electron.ipcRenderer.send('launch-bosszhipin-login-page-with-preload-extension')
|
mountWaitForLoginDialog()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user