From b74ab06229c17c32bc64f143c3a629a27ee7b1d1 Mon Sep 17 00:00:00 2001 From: reruin Date: Thu, 21 May 2020 18:20:07 +0800 Subject: [PATCH] + enhanced encryption --- app/controllers/sharelist.js | 6 +-- app/middleware/koa-paths.js | 3 ++ app/plugins/cmd.core.js | 17 ++++++-- app/services/plugin.js | 14 +++++-- app/services/sharelist.js | 76 ++++++++++++++++++++++++++---------- app/views/default/auth.pug | 6 ++- plugins/drive.189cloud.js | 28 ++++++++----- plugins/drive.caiyun.js | 15 ++++--- 8 files changed, 117 insertions(+), 48 deletions(-) diff --git a/app/controllers/sharelist.js b/app/controllers/sharelist.js index c6eccebd..37d9e318 100644 --- a/app/controllers/sharelist.js +++ b/app/controllers/sharelist.js @@ -16,9 +16,9 @@ const isProxyPath = (path , paths) => { const output = async (ctx , data)=>{ - const isPreview = ctx.request.querystring.indexOf('preview') >= 0 + const isPreview = ctx.runtime.isPreview - const isforward = ctx.request.querystring.indexOf('forward') >= 0 + const isforward = ctx.runtime.isForward const downloadLinkAge = config.getConfig('max_age_download') @@ -190,7 +190,7 @@ module.exports = { }) } else if(data.type == 'auth_response'){ - let result = {status:0 , message:"success"} + let result = {status:0 , message:"success" , rurl:ctx.query.rurl} if(!data.result){ result.status = 403 result.message = '验证失败' diff --git a/app/middleware/koa-paths.js b/app/middleware/koa-paths.js index 79d99e64..6a9c769f 100644 --- a/app/middleware/koa-paths.js +++ b/app/middleware/koa-paths.js @@ -34,6 +34,9 @@ const parseConfig = (str) => { if(params.has('preview')){ ret.isPreview = true } + if(params.has('forward')){ + ret.isForward = true + } if(params.has('sort')){ let s = params.get('sort') let r = {} diff --git a/app/plugins/cmd.core.js b/app/plugins/cmd.core.js index 84513163..a3a3e1e8 100644 --- a/app/plugins/cmd.core.js +++ b/app/plugins/cmd.core.js @@ -114,21 +114,26 @@ module.exports = ({ cache , getVendor , getConfig , getRuntime , updateFolder , let hit = root() let paths = (p == '' || p == '/') ? [] : p.replace(/^\//,'').split('/').map(i => decodeURIComponent(i)) - let idx = paths.length - let isRoot = idx == 0 + let idx = 0 + let isRoot = paths.length == 0 - //逆向查询节点 + //逆向查询节点 path -> filemeta { protocol , id , type } -> filedata while( idx >= 0 ){ let cur = '/' + paths.slice(0,idx).join('/') let content = nodeCache[cur] if( content ){ hit = content + //过滤器拦截 + if(filter && filter(hit , paths.slice(0,idx+1))){ + return hit; + } idx-- break }else{ idx-- } } + if(hit.protocol == 'root'){ if( hit.children && hit.children.length == 1 ){ @@ -152,7 +157,6 @@ module.exports = ({ cache , getVendor , getConfig , getRuntime , updateFolder , continue } - let vendor = getVendor(hit.protocol) if (hit.lnk) { @@ -202,6 +206,11 @@ module.exports = ({ cache , getVendor , getConfig , getRuntime , updateFolder , } } + //过滤器拦截 + if(filter && filter(hit , paths.slice(0,idx+1))){ + return hit; + } + } return hit diff --git a/app/services/plugin.js b/app/services/plugin.js index 758eb5bb..4e6d63d7 100644 --- a/app/services/plugin.js +++ b/app/services/plugin.js @@ -52,8 +52,14 @@ var resourcesCount = 0 const recognize = async (image , type, lang) => { let server = config.getConfig('ocr_server') if(server){ - let resp = await http.post(server,{ image , type, lang },{json:true}) - if(resp.body){ + let resp + try{ + resp = await http.post(server,{ image , type, lang },{json:true}) + }catch(e){ + //console.log(e) + } + + if(resp && resp.body){ return { error:false , result:resp.body.result} } } @@ -64,10 +70,10 @@ const recognize = async (image , type, lang) => { /* * 根据文件id获取详情 */ -const getSource = async (id , driverName) => { +const getSource = async (id , driverName , data) => { if(driveMap.has(driverName)){ let vendor = getDrive(driverName) - let d = await vendor.file(id , { req: config.getRuntime('req') } ) + let d = await vendor.file(id , { req: config.getRuntime('req') , data } ) if(d.outputType === 'file'){ return await getFile(d.url) } diff --git a/app/services/sharelist.js b/app/services/sharelist.js index fc1e9c78..10958771 100644 --- a/app/services/sharelist.js +++ b/app/services/sharelist.js @@ -8,21 +8,35 @@ const format = require('../utils/format') const { getDrive, getAuth, getStream , getSource, updateLnk, checkAuthority, updateFile, updateFolder , getPreview , isPreviewable , command } = require('./plugin') // const wrapReqStream = require('../utils/wrapReqStream') -const diff = (a, b) => { - let ret = [] - b.forEach((v, i) => { - if (v != a[i]) { - ret.push(v) - } - }) - return ret -} - -const requireAuth = (data) => !!(data.children && data.children.find(i=>(i.name == '.passwd'))) class ShareList { constructor(root) { + this.passwdPaths = new Set() + } + + async diff(a,b){ + let ret = [] + b.forEach((v, i) => { + if (v != a[i]) { + ret.push(v) + } + }) + return ret + } + + access(data){ + return !!(data.children && data.children.find(i=>(i.name == '.passwd'))) + } + searchPasswdPath(req){ + for(let i = 1 ; i <= req.paths.length ; i++){ + let path = '/'+req.paths.slice(0,i).join('/') + if( this.passwdPaths.has(path) && req.access.has(path) == false && !req.isAdmin){ + return path + } + } + + return null } async path(req) { @@ -59,17 +73,39 @@ class ShareList { } } else{ - let data = await command('ls' , req.paths.join('/') , function(data){ - if( requireAuth(data) && req.access.has(req.path) == false && !req.isAdmin) { - return true + let passwdPath = this.searchPasswdPath(req) + let targetPath = '/'+req.paths.join('/') , currentPath = '' + if(!passwdPath || passwdPath == targetPath || targetPath == '/'){ + let currentPath + let data = await command('ls' , targetPath, (data , paths) => { + currentPath = '/' + paths.join('/') + if( this.access(data) && req.access.has(currentPath) == false) { + this.passwdPaths.add(currentPath) + return true + } + }) + if(data.type == 'folder'){ + if(currentPath && targetPath != currentPath){ + return { type:'redirect', 'redirect':currentPath+'?rurl='+targetPath } + }else{ + if( this.access(data) && req.access.has(req.path) == false && !req.isAdmin) { + this.passwdPaths.add(targetPath) + data.type = 'auth' + }else{ + if(this.passwdPaths.has(targetPath)){ + this.passwdPaths.delete(targetPath) + } + } + return data + } + }else{ + return data } - }) - - //管理员模式无需密码 - if( requireAuth(data) && req.access.has(req.path) == false && !req.isAdmin) { - data.type = 'auth' + + }else{ + return { type:'redirect', 'redirect':passwdPath+'?rurl='+targetPath } } - return data + } } diff --git a/app/views/default/auth.pug b/app/views/default/auth.pug index 7a5c69ea..5e6a7f6d 100644 --- a/app/views/default/auth.pug +++ b/app/views/default/auth.pug @@ -26,7 +26,11 @@ block content success:function(resp){ $('button').removeClass('loading') if(resp.status == 0){ - location.reload() + if(resp.rurl){ + location.href = resp.rurl + }else{ + location.reload() + } }else{ alert(resp.message) } diff --git a/plugins/drive.189cloud.js b/plugins/drive.189cloud.js index cd87830b..f48d9115 100644 --- a/plugins/drive.189cloud.js +++ b/plugins/drive.189cloud.js @@ -41,7 +41,7 @@ class Manager { async ocr(image){ let resp = await this.recognize(image,'189cloud') - let ret = { error:resp.error } + let ret = { error:resp.error , msg:resp.msg } if(!resp.error){ let code = resp.result.replace(/[^a-z0-9]/i,'') // retry @@ -69,9 +69,11 @@ class Manager { let hit = this.clientMap[data.username] if(hit){ if( !hit.cookies || (Date.now() - hit.updated_at) > COOKIE_MAX_AGE ){ - let result = await this.create(hit.username , hit.password) + let { result , msg } = await this.create(hit.username , hit.password) if( result ){ hit = this.clientMap[data.username] + }else{ + return { error : msg } } } } @@ -188,6 +190,7 @@ class Manager { //服务不可用 if(error){ formdata.validateCode = '' + msg = '验证码识别接口无法使用' break; } else if(code){ @@ -226,7 +229,6 @@ class Manager { await this.updateHandle(this.stringify({username , password})) this.clientMap[username] = client - console.log('cookies>>',cookies) result = true break; }else{ @@ -235,9 +237,6 @@ class Manager { } - if( needcaptcha && !formdata.validateCode){ - msg = '请设置验证码识别接口!' - } return { result , msg } } @@ -247,7 +246,7 @@ class Manager { if(data.username){ let hit = this.clientMap[data.username] if(hit){ - await this.create(hit.username , hit.password) + return await this.create(hit.username , hit.password) } } } @@ -292,6 +291,10 @@ module.exports = ({ request, cache, getConfig, querystring, base64, saveDrive, g let { path, cookies, username, error } = await manager.get(id) + if( error ){ + return { id, type: 'folder', protocol: defaultProtocol,body: await install(error) } + } + if( cookies ) { return { cookies , path , username } @@ -318,8 +321,13 @@ module.exports = ({ request, cache, getConfig, querystring, base64, saveDrive, g resp = await request({async:true,...rest}) //cookie失效 if(resp.headers['Content-Type'] && resp.headers['Content-Type'].includes('text/html')){ - await manager.update(id) - continue + let { result , msg } = await manager.update(id) + if( result ){ + resp = { msg } + break; + }else{ + continue + } }else{ break; } @@ -361,7 +369,7 @@ module.exports = ({ request, cache, getConfig, querystring, base64, saveDrive, g }) if (!resp || !resp.body) { - return { id, type: 'folder', protocol: defaultProtocol,body:'解析错误' } + return { id, type: 'folder', protocol: defaultProtocol,body:resp.msg || '解析错误' } } let children = resp.body.data.map( file => { diff --git a/plugins/drive.caiyun.js b/plugins/drive.caiyun.js index d71c1a23..50311e3b 100644 --- a/plugins/drive.caiyun.js +++ b/plugins/drive.caiyun.js @@ -83,9 +83,11 @@ class Manager { let hit = this.clientMap[data.username] if(hit){ if( !hit.cookie || (Date.now() - hit.updated_at) > COOKIE_MAX_AGE ){ - let result = await this.create(hit.username , hit.password) + let { result , msg } = await this.create(hit.username , hit.password) if( result ){ hit = this.clientMap[data.username] + }else{ + return { error: msg } } } } @@ -175,6 +177,7 @@ class Manager { if(error){ console.log('服务不可用') formdata.validateCode = '' + msg = '验证码识别服务不可用!' break; } else if(code){ @@ -241,9 +244,6 @@ class Manager { } } - if( needcaptcha && !formdata.validate){ - msg = '请设置验证码识别接口!' - } return { result , msg } } @@ -253,7 +253,7 @@ class Manager { if(data.username){ let hit = this.clientMap[data.username] if(hit){ - await this.create(hit.username , hit.password) + return await this.create(hit.username , hit.password) } } } @@ -340,8 +340,11 @@ module.exports = ({ request, cache, getConfig, querystring, base64, saveDrive, g if (!predata.cookie) return predata - let { path, cookie , username } = await prepare(id) + let { path, cookie , username , error } = await prepare(id) + if(error){ + return { id, type: 'folder', protocol: defaultProtocol,body:'异常:'+error } + } let r = cache.get(id) if (r) { if (