show cookie assistant when find cookie invalid after launch; extract check cookie format correct;

This commit is contained in:
geekgeekrun
2024-03-03 19:37:24 +08:00
parent 7e5e37c512
commit 72b2919d19
4 changed files with 78 additions and 37 deletions
+27
View File
@@ -0,0 +1,27 @@
export const checkCookieListFormat = (cookies: Array<Record<string, string>>) => {
const allExpectKeySet = new Set([
'name',
'value',
'domain',
'path',
'secure',
'session',
'httpOnly'
])
return Array.isArray(cookies) &&
cookies.length &&
cookies.every((it) => {
const currentOwnedKeySet = new Set(Object.keys(it))
if (currentOwnedKeySet.size < allExpectKeySet.size) {
return false
}
const allExpectKeyArr = [...allExpectKeySet]
for (let i = 0; i < allExpectKeyArr.length; i++) {
if (!currentOwnedKeySet.has(allExpectKeyArr[i])) {
return false
}
}
return true
})
}
+11 -2
View File
@@ -9,13 +9,12 @@ import {
configFileNameList, configFileNameList,
readConfigFile, readConfigFile,
writeConfigFile, writeConfigFile,
storageFileNameList,
readStorageFile, readStorageFile,
writeStorageFile writeStorageFile
} from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
import { ChildProcess } from 'child_process' import { ChildProcess } from 'child_process'
import * as JSONStream from 'JSONStream' import * as JSONStream from 'JSONStream'
import { checkCookieListFormat } from '../../common/utils/cookie'
import { import {
DOWNLOAD_ERROR_EXIT_CODE, DOWNLOAD_ERROR_EXIT_CODE,
getAnyAvailablePuppeteerExecutable getAnyAvailablePuppeteerExecutable
@@ -93,6 +92,11 @@ export function createMainWindow(): void {
]) ])
}) })
ipcMain.handle('read-storage-file', async (ev, payload) => {
ensureStorageFileExist()
return await readStorageFile(payload.fileName)
})
ipcMain.handle('write-storage-file', async (ev, payload) => { ipcMain.handle('write-storage-file', async (ev, payload) => {
ensureStorageFileExist() ensureStorageFileExist()
@@ -264,6 +268,11 @@ export function createMainWindow(): void {
} }
}) })
ipcMain.handle('check-boss-zhipin-cookie-file', () => {
const cookies = readStorageFile('boss-cookies.json')
return checkCookieListFormat(cookies)
})
mainWindow!.once('closed', () => { mainWindow!.once('closed', () => {
mainWindow = null mainWindow = null
}) })
@@ -2,28 +2,38 @@
<el-dialog <el-dialog
v-bind="$attrs" v-bind="$attrs"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="!cookieInvalid"
title="Boss直聘 Cookie助手" title="Boss直聘 Cookie助手"
:width="720" :width="720"
top="20px" top="20px"
lock-scroll lock-scroll
:show-close="!cookieInvalid"
> >
<el-alert type="warning" title="需要获取您的Boss直聘Cookie才能继续"> <el-alert
v-if="cookieInvalid"
type="warning"
:closable="false"
title="需要获取您的Boss直聘Cookie才能继续"
>
由于您是首次使用本程序或者您之前使用的Boss直聘账号登录状态失效因此您需要重新获取登录凭证 由于您是首次使用本程序或者您之前使用的Boss直聘账号登录状态失效因此您需要重新获取登录凭证
</el-alert> </el-alert>
<div ml1em mt1em> <div ml1em mt1em line-height-normal>
如果您了解Cookie如何获取Cookie请打开您已登录过Boss直聘的浏览器使用 如果您了解如何获取Cookie了解有效的Cookie格式可以直接在下方输入框中进行编辑<br />
手动编辑较为麻烦建议您打开已登录过Boss直聘的浏览器使用
<a <a
color-blue color-blue
decoration-none decoration-none
href="javascript:void(0)" href="javascript:void(0)"
@click.prevent="handleEditThisCookieExtensionStoreLinkClick" @click.prevent="handleEditThisCookieExtensionStoreLinkClick"
>EditThisCookie 扩展程序/插件</a >EditThisCookie 扩展程序</a
> >
进行复制然后粘贴在下方输入框中<br /> 复制Cookie然后粘贴在下方输入框中<br />
格式为被序列化为JSON的数组不含两侧引号 格式为被序列化为JSON的数组不含两侧引号
</div> </div>
<br /> <br />
<div ml1em>如果您不了解相关概念请按照以下步骤进行操作</div> <div ml1em line-height-normal>
如果您不了解Cookie相关概念或者不能访问Chrome扩展程序商店下载EditThisCookie来获取Cookie请按照以下步骤进行操作
</div>
<ol lh-2em mt-0> <ol lh-2em mt-0>
<li> <li>
<el-button size="small" type="primary" font-size-inherit @click="handleClickLaunchLogin" <el-button size="small" type="primary" font-size-inherit @click="handleClickLaunchLogin"
@@ -32,8 +42,9 @@
启动浏览器 启动浏览器
</li> </li>
<li>按照正常流程通过 <b>短信验证码/二维码/微信小程序</b> 登录您的Boss直聘账号</li> <li>按照正常流程通过 <b>短信验证码/二维码/微信小程序</b> 登录您的Boss直聘账号</li>
<li>接下来将自动进行一些页面跳转最终将会停留在首页</li>
<li> <li>
如果流程顺利登录后预计5-10秒内您将可以在下方输入框看到您的Cookie 登录后预计5-10秒内具体取决于您的网速您的Cookie将被自动填入下方输入框
<details> <details>
<summary color-orange cursor-pointer>我已完成登录但Cookie一直没出现</summary> <summary color-orange cursor-pointer>我已完成登录但Cookie一直没出现</summary>
<div ml-2em max-h-200px of-auto> <div ml-2em max-h-200px of-auto>
@@ -94,6 +105,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button v-if="!cookieInvalid" @click="dispose">关闭</el-button>
<el-button type="primary" @click="handleSubmit">保存Cookie</el-button> <el-button type="primary" @click="handleSubmit">保存Cookie</el-button>
</template> </template>
</el-dialog> </el-dialog>
@@ -102,10 +114,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ElForm, ElMessage } from 'element-plus' import { ElForm, ElMessage } from 'element-plus'
import { ref, onUnmounted, onMounted } from 'vue' import { ref, onUnmounted, onMounted } from 'vue'
import { checkCookieListFormat } from '../../../../common/utils/cookie'
const props = defineProps({ const props = defineProps({
dispose: Function dispose: Function
}) })
const cookieInvalid = ref(false)
enum LOGIN_COOKIE_WAITING_STATUS { enum LOGIN_COOKIE_WAITING_STATUS {
INIT, INIT,
WAITING_FOR_LOGIN, WAITING_FOR_LOGIN,
@@ -139,33 +155,7 @@ const formRules = {
return return
} }
const allExpectKeySet = new Set([ if (!checkCookieListFormat(JSON.parse(formContent.value.collectedCookies))) {
'name',
'value',
'domain',
'path',
'secure',
'session',
'httpOnly'
])
if (
!Array.isArray(arr) ||
!arr.length ||
!arr.every((it) => {
const currentOwnedKeySet = new Set(Object.keys(it))
if (currentOwnedKeySet.size < allExpectKeySet.size) {
return false
}
const allExpectKeyArr = [...allExpectKeySet]
for (let i = 0; i < allExpectKeyArr.length; i++) {
if (!currentOwnedKeySet.has(allExpectKeyArr[i])) {
return false
}
}
return true
})
) {
cb(new Error(`Cookie格式无效 - 部分字段缺失;建议使用EditThisCookie扩展程序进行复制。`)) cb(new Error(`Cookie格式无效 - 部分字段缺失;建议使用EditThisCookie扩展程序进行复制。`))
return return
} }
@@ -220,9 +210,18 @@ const handleBossZhipinLoginPageClosed = () => {
} }
} }
onMounted(() => { onMounted(async () => {
electron.ipcRenderer.once('BOSS_ZHIPIN_COOKIE_COLLECTED', handleCookieCollected) electron.ipcRenderer.once('BOSS_ZHIPIN_COOKIE_COLLECTED', handleCookieCollected)
electron.ipcRenderer.on('BOSS_ZHIPIN_LOGIN_PAGE_CLOSED', handleBossZhipinLoginPageClosed) electron.ipcRenderer.on('BOSS_ZHIPIN_LOGIN_PAGE_CLOSED', handleBossZhipinLoginPageClosed)
const cookieFileContent = await electron.ipcRenderer.invoke('read-storage-file', {
fileName: 'boss-cookies.json'
})
if (checkCookieListFormat(cookieFileContent)) {
formContent.value.collectedCookies = JSON.stringify(cookieFileContent, null, 2)
} else {
cookieInvalid.value = true
}
}) })
onUnmounted(() => { onUnmounted(() => {
electron.ipcRenderer.removeListener('BOSS_ZHIPIN_COOKIE_COLLECTED', handleCookieCollected) electron.ipcRenderer.removeListener('BOSS_ZHIPIN_COOKIE_COLLECTED', handleCookieCollected)
@@ -3,6 +3,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onUnmounted } from 'vue' import { onUnmounted } from 'vue'
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 unmountedCbs: Array<InstanceType<typeof Function>> = [] const unmountedCbs: Array<InstanceType<typeof Function>> = []
onUnmounted(() => { onUnmounted(() => {
@@ -18,5 +19,10 @@ onUnmounted(() => {
if (Object.values(checkDependenciesResult).includes(false)) { if (Object.values(checkDependenciesResult).includes(false)) {
mountDependenciesSetupProgressIndicatorDialog(checkDependenciesResult) mountDependenciesSetupProgressIndicatorDialog(checkDependenciesResult)
} }
const isCookieFileValid = await electron.ipcRenderer.invoke('check-boss-zhipin-cookie-file')
if (!isCookieFileValid) {
mountWaitForLoginDialog()
}
})() })()
</script> </script>