Feature: add privacy policy

This commit is contained in:
PiEgg
2021-04-10 21:01:55 +08:00
parent 06d40ef7f6
commit 992ff35936
15 changed files with 186 additions and 76 deletions

View File

@@ -16,6 +16,7 @@ import picgo from '@core/picgo'
import pasteTemplate from '#/utils/pasteTemplate'
import pkg from 'root/package.json'
import { handleCopyUrl } from '~/main/utils/common'
import { privacyManager } from '~/main/utils/privacyManager'
let contextMenu: Menu | null
let menu: Menu | null
let tray: Tray | null
@@ -76,6 +77,12 @@ export function createContextMenu () {
db.set('settings.showUpdateTip', !value)
}
},
{
label: '隐私协议',
click () {
privacyManager.show(false)
}
},
{
label: '重启应用',
click () {

View File

@@ -11,8 +11,8 @@ import windowManager from 'apis/app/window/windowManager'
import { IWindowList } from 'apis/app/window/constants'
import util from 'util'
import { IPicGo } from 'picgo/dist/src/types'
import { showNotification } from '~/main/utils/common'
import { BAIDU_TONGJI_EVENT } from '~/universal/events/constants'
import { showNotification, calcDurationRange } from '~/main/utils/common'
import { TALKING_DATA_EVENT } from '~/universal/events/constants'
const waitForShow = (webcontent: WebContents) => {
return new Promise<void>((resolve, reject) => {
@@ -37,14 +37,18 @@ const waitForRename = (window: BrowserWindow, id: number): Promise<string|null>
})
}
const handleBaiduTongJi = (webContents: WebContents, options: IAnalyticsData) => {
const data: IBaiduTongJiOptions = {
category: 'upload',
action: options.fromClipboard ? 'clipboard' : 'files', // 上传剪贴板图片还是选择的文件
opt_label: options.type,
opt_value: options.duration
const handleTalkingData = (webContents: WebContents, options: IAnalyticsData) => {
const data: ITalkingDataOptions = {
EventId: 'upload',
Label: options.type,
MapKv: {
by: options.fromClipboard ? 'clipboard' : 'files', // 上传剪贴板图片还是选择的文文件
count: options.count, // 上传的数量
duration: calcDurationRange(options.duration || 0), // 上传耗时
type: options.type
}
}
webContents.send(BAIDU_TONGJI_EVENT, data)
webContents.send(TALKING_DATA_EVENT, data)
}
class Uploader {
@@ -120,7 +124,7 @@ class Uploader {
this.uploading = false
if (ctx.output.every((item: ImgInfo) => item.imgUrl)) {
if (this.webContents) {
handleBaiduTongJi(this.webContents, {
handleTalkingData(this.webContents, {
fromClipboard: !img,
type: db.get('picBed.current') || 'smms',
count: img ? img.length : 1,

View File

@@ -14,10 +14,7 @@ import getPicBeds from '~/main/utils/getPicBeds'
import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
import bus from '@core/bus'
import {
TOGGLE_SHORTKEY_MODIFIED_MODE,
BAIDU_TONGJI_INIT,
BAIDU_TONGJI_CODE,
BAIDU_TONGJI_INIT_RES
TOGGLE_SHORTKEY_MODIFIED_MODE
} from '#/events/constants'
import {
uploadClipboardFiles,
@@ -25,7 +22,6 @@ import {
} from '~/main/apis/app/uploader/apis'
import picgoCoreIPC from './picgoCoreIPC'
import { handleCopyUrl } from '~/main/utils/common'
import axios from 'axios'
export default {
listen () {
@@ -145,26 +141,6 @@ export default {
ipcMain.on('updateServer', () => {
server.restart()
})
ipcMain.on(BAIDU_TONGJI_INIT, (evt: IpcMainEvent) => {
axios.get(`https://hm.baidu.com/hm.js?${BAIDU_TONGJI_CODE}`, {
headers: {
referer: 'https://molunerfinn.com/'
}
}).then(res => {
if (res.status === 200) {
let scriptContent: string = res.data
// thanks to https://github.com/joehecn/electron-baidu-tongji/blob/master/index.js
const source = '(h.c.b.su=h.c.b.u||document.location.href),h.c.b.u=f.protocol+"//"+document.location.host+'
if (scriptContent.includes(source)) {
const target = '(h.c.b.su=h.c.b.u||"https://"+c.dm[0]+a[1]),h.c.b.u="https://"+c.dm[0]+'
const target2 = '"https://"+c.dm[0]+window.location.pathname+window.location.hash'
scriptContent = scriptContent.replace(source, target).replace(/window.location.href/g, target2)
}
evt.sender.send(BAIDU_TONGJI_INIT_RES, scriptContent)
}
})
})
},
dispose () {}
}

View File

@@ -2,7 +2,6 @@ import {
app,
globalShortcut,
protocol,
dialog,
Notification
} from 'electron'
import {
@@ -31,6 +30,7 @@ import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
import { getUploadFiles } from '~/main/utils/handleArgv'
import db from '#/datastore'
import bus from '@core/bus'
import { privacyManager } from '~/main/utils/privacyManager'
const isDevelopment = process.env.NODE_ENV !== 'production'
class LifeCycle {
@@ -54,6 +54,10 @@ class LifeCycle {
console.error('Vue Devtools failed to install:', e.toString())
}
}
const res = await privacyManager.init()
if (!res) {
return app.quit()
}
windowManager.create(IWindowList.TRAY_WINDOW)
windowManager.create(IWindowList.SETTING_WINDOW)
createTray()

View File

@@ -1,5 +1,5 @@
import db from '#/datastore'
import { clipboard, Notification } from 'electron'
import { clipboard, Notification, dialog } from 'electron'
export const handleCopyUrl = (str: string): void => {
if (db.get('settings.autoCopy') !== false) {
@@ -18,7 +18,8 @@ export const showNotification = (options: IPrivateShowNotificationOption = {
}) => {
const notification = new Notification({
title: options.title,
body: options.body
body: options.body,
icon: options.icon || undefined
})
const handleClick = () => {
if (options.clickToCopy) {
@@ -31,3 +32,40 @@ export const showNotification = (options: IPrivateShowNotificationOption = {
})
notification.show()
}
export const showMessageBox = (options: any) => {
return new Promise<IShowMessageBoxResult>(async (resolve, reject) => {
dialog.showMessageBox(
options
).then((res) => {
resolve({
result: res.response,
checkboxChecked: res.checkboxChecked
})
})
})
}
export const calcDurationRange = (duration: number) => {
if (duration < 1000) {
return 500
} else if (duration < 1500) {
return 1000
} else if (duration < 3000) {
return 2000
} else if (duration < 5000) {
return 3000
} else if (duration < 7000) {
return 5000
} else if (duration < 10000) {
return 8000
} else if (duration < 12000) {
return 10000
} else if (duration < 20000) {
return 15000
} else if (duration < 30000) {
return 20000
}
// max range
return 100000
}

View File

@@ -0,0 +1,61 @@
import db from '#/datastore'
import { ipcMain } from 'electron'
import { showMessageBox } from '~/main/utils/common'
import { SHOW_PRIVACY_MESSAGE } from '~/universal/events/constants'
class PrivacyManager {
async init () {
ipcMain.on(SHOW_PRIVACY_MESSAGE, () => {
this.show(false)
})
if (db.get('settings.privacyEnsure') !== true) {
const res = await this.show(true)
// cancel
if (res.result === 1) {
return false
} else {
db.set('settings.privacyEnsure', true)
return true
}
}
return true
}
async show (showCancel = true) {
const res = await showMessageBox({
type: 'info',
buttons: showCancel ? ['Yes', 'No'] : ['Yes'],
title: '隐私协议',
message: `
本软件尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更优质的服务,本软件会按照本隐私权政策的规定使用和收集您的一些行为信息。您在同意本软件服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本软件服务使用协议不可分割的一部分,如果不同意将无法使用。本协议会定期更新。
1.适用范围
a)在您使用本软件时,本软件会记录的您对本软件的一些操作行为信息,包括但不限于您使用本软件进行文件上传的耗时、类型、数量等信息。
2.信息的使用
a)在获得您的使用数据之后,本软件会将其上传至数据分析服务器,以便分析数据后,提供给您更好的服务。
3.信息披露
a)本软件不会将您的信息披露给不受信任的第三方。
b)根据法律的有关规定,或者行政或司法机构的要求,向第三方或者行政、司法机构披露;
c)如您出现违反中国有关法律、法规或者相关规则的情况,需要向第三方披露;
4.信息安全
a)本软件不会收集您的个人信息、密钥信息等隐私信息,所收集的信息仅仅作为改善软件、优化体验、了解软件日活等用途。
`
})
return res
}
}
const privacyManager = new PrivacyManager()
export {
privacyManager
}