1、使用 idoc 可实现看云基本的文档创作功能;
2、非常适合团队或者个人内部使用(写书、写笔记、写 api 文档都可以)
3、目前仅支持 markdown 编辑器(markdown 渲染仍有部分问题需要解决)
4、源码已发布在 github,项目地址:https://github.com/coderzheng/idoc
5、使用 php 原生代码编写,不依赖任何框架
6、Enjoy, http://idoc.codespeaking.com
1
qile1 2019-10-07 23:16:49 +08:00 via Android
如果我想把编辑的这些内容打印成纸质的有啥好办法分页没?如果我打印了一张半纸,我又添加了一些内容,如何在剩下的半张纸上继续从上次打印位置打印文件
|
2
rustkeyboard OP @qile1,打印了一张半纸的时候,临时再重新编辑文章内容,之后再继续打印?
|
4
windowsma 2019-10-08 09:08:31 +08:00
不需要输入用户名密码也可以登录,这是怎么实现的(╬▔皿▔)凸
|
5
xiaotuzi 2019-10-08 09:18:03 +08:00 via iPhone
我想爬看云的文档…
|
6
qile1 2019-10-08 09:35:16 +08:00 via Android
@rustkeyboard 只是添加内容,如果是编辑了,估计得重新打印了
比如第一次我书写如下笔记 '''20191020 测试新程序,调研准备开发 ''' 我把上面内容打印到一张纸上,可能只打印了一行 隔几天,又添加了一些内容 '''20191025 调研完成,准备编写文档 ''' 有没有办法打印到原来那张纸上,不要覆盖原来打印内容,这样就可以把自己的记录打印到一起,每次打印完都是连续的 |
7
yuankui 2019-10-08 10:32:06 +08:00
php 果然是最好的语言
|
8
rustkeyboard OP @windowsma,一个小 bug 哈,已修复。
|
9
rustkeyboard OP @qile1,你这个问题有点意思。如果能实现这个需求,那么打印程序要完成以下步骤:
1、程序检测到纸张上已经存在有打印的内容(比如一张纸上有 3 行内容,第一行 aaa,第二行 bbb,第三行 ccc),自动获取最后一行的内容(ccc),并记录纸张上 ccc 行所在的位置; 2、程序将 ccc 这一行和即将进行打印的文本内容进行比较,自动定位到文本内容的 ccc 行; 3、程序发出指令给打印机,从文本内容 ccc 行下面的内容开始打印,并且这里最重要的一点是,需要告诉打印机,打印的位置是从纸张的 ccc 行下面一行开始打印。 然后我立刻按下 ctrl + p,查看了一下打印的设置界面,结论是:即使是手动设置里面也没有这么高级的选项。而且,在第二步这里存在一个似乎无法解决的问题:如果文本内容中包含有两个同样的 ccc 行,那要取哪个 ccc 行呢? |
10
lanyeol 2019-10-08 11:11:28 +08:00
支持楼主
|
11
mokeyjay 2019-10-08 11:21:46 +08:00
开源精神值得鼓励,不过需要提升的地方还有很多。举例:
- 数据库连接请使用 PDO,而不是 mysqli - 对于新手而言不依赖框架并不值得骄傲,反而容易导致很多安全隐患 - 前端体验较差,建议学习 ajax |
12
460881773 2019-10-08 11:25:14 +08:00
通过 4 楼有感 ,随便试试了 账号 1 密码 1 登录成功! 于是修改密码 123456 现在获得用户名 1 密码 123456 (╬▔皿▔)凸
|
15
wzhjii0 2019-10-08 11:58:29 +08:00
|
16
dafengchui 2019-10-08 12:22:37 +08:00
|
17
markgor 2019-10-08 13:25:10 +08:00
赞成 11L +1
提提几个问题: 1、输入内容未进行过滤。 创建主题时候,直接输入 JS 代码就能直接 XSS 注入了。(我输入了个</script>window.location.href="http://www.v2ex.com";</script>,現在訪問跳轉來 V2EX 了。 2、權限控制沒做好。 通過 POSTMAN,直接修改參數提交到 admin/api.php 就可以了。哪怕不是自己創建的。 3、存在 SQL 注入點- |
18
xbx1209 2019-10-08 13:45:04 +08:00
@rustkeyboard #9
为啥不换个思路 程序上记住本次打印内容至 xx 行 后来新增了新内容后,内容变成了 A 当要打印新增内容时 程序生成新的内容 B:第 1 行至 xx 行为空行,然后接下去上次打印后新增编辑内容 打印机这边手动插入上次的纸 然后就打印内容 B 就好了,打印出来的结果就跟内容 A 是一样的 |
19
cydian 2019-10-08 13:51:45 +08:00 via Android
好东西。坐等更新楼上的安全漏洞。
很想部署,但是楼上说的安全漏洞令人担忧啊 |
20
anyc007 2019-10-08 13:53:26 +08:00
赞同楼上,有问题哦 xss 之类
|
21
markgor 2019-10-08 13:57:53 +08:00
換成 PDO,參數綁定下,SQL 注入問題解決。
XSS 注入的問題,過濾下,可以用 HTMLPurifier 來過濾,千萬不要只是在前端進行過濾。 權限控制,沒什麼好說的。進行修改刪除添加的時候判斷下資源是否屬於當前用戶。 |
22
markgor 2019-10-08 14:05:27 +08:00
另外 LS 說到打印的問題。
其實沒那麼複雜吧。 每次保存後記錄本次新增內容, 頁面生成的時候根據每次新增的內容用不同 DIV 包裹著,點擊打印的時候讓用戶選擇打印哪些內容,不需要打印的用 visibility 來佔位隱藏,配合 jqprint 就可以了。 不過實際上還會有些問題,例如用戶是修改了上次的內容,那那種辦法都不實際。 而且我覺得這個問題有點杠,不是不可能實現,而是沒必要實現。日常使用中,就算反面打印(手工)都會出現放錯紙,何況現在要增量打印?而且紙張價格不貴吧.......別扯環保問題,環保問題是有錢人才談論的。 |
23
rustkeyboard OP |
24
markgor 2019-10-08 15:44:18 +08:00
@rustkeyboard
> $pids = $_SESSION['pids']; > $prid = $_REQUEST['prid']; > if ( strpos($pids, $prid) === false ) { > echo json_encode(['status'=>'FAIL', 'msg'=>'非法的操作!']); > exit; > } 如沒猜錯你是想判斷這兩個 ID 是否相等,不相等就沒權限處理吧? 但你這裡的 strpos 用的我是相當迷茫..... 查找 登錄 ID 在提交 ID 首次出現的位置。 那麼假設登錄 ID 固定為 12,當我需要改用戶 ID 為 13 的文章, 我只需要提交 prid=1 或者 2 那樣我就能繞過去了. 為什麼你不用 === 來判斷? $pids == $prid ,這樣不是更好嗎? 然後突然間我發現另一個問題, 為什麼你會在這裡進行判斷, 就算你用==來判斷,最終執行 SQL 的時候,還是成功執行了,為什麼不在 SQL 裡的 where 加條件? update xxx set xxxx WHERE pids = $prid 然後根據影響條數來判斷操作成功失敗? |
25
dafengchui 2019-10-08 16:05:35 +08:00
@rustkeyboard 什么时候可以用类似左侧导航的模版, 我等很久了.
|
26
rustkeyboard OP @markgor,这里确实有点问题,刚刚已经修复了。
|
27
rustkeyboard OP @dafengchui , 左侧导航这个需求,可以考虑将来站点功能完善了之后,采用更换模板的问题来解决。已经加在需求列表中,等前面主要的功能都完成,就会添加,感谢关注, ^_^。
|
28
markgor 2019-10-08 17:09:19 +08:00
@rustkeyboard
[url]http://idoc.codespeaking.com/book.php?id=8},function(a){});alert(123123);var%20a%20=%20({[/url] CSRF 漏洞 老實說,如果您覺得聽不進去就算了, 先拋開體驗度和功能,這套代碼要正式使用還有一大堆問題需要修復。 而且看你開源的代碼,感覺應該屬於練手系列吧? 你有個 api.php 的文件,是只處理後台的請求?然後前台的請求就分散各個頁面單獨處理, 這樣的話對於你後期擴展功能會很不方便。 另外看你 book.php 這個頁面,其實沒必要 BOOK.PHP 執行一次查詢,然後再通過 AJAX,獲取另一次查詢的結果。與其這樣還不如直接在 book.php 里完成查詢,或 BOOK.Php 改為靜態,內容通過一次 ajax 進行查詢回來? 還有 timestamp 這個類型真的不建議使用,項目大了之後到 2038 年就後悔死自己了。 |
29
rustkeyboard OP @markgor,已修复。
|
30
falcon05 2019-10-08 22:19:10 +08:00 via iPhone
卧槽,这简直教科书式的安全漏洞
|
31
rustkeyboard OP @falcon05,idoc 现在像是个初生的婴儿,由于没有框架的防护机制,难免会存在一些问题。有漏洞是正常的,想办法找出漏洞并解决它才是重点。
|
32
markgor 2019-10-09 16:34:08 +08:00
|
33
rustkeyboard OP @markgor,你确定这里有问题? prid 可以伪造,但是$prids 是登录之后是由后端查询数据库自动保存在 session 中的。
再回来讲一下你说的可能存在的问题(24L), "那麼假設登錄 ID 固定為 12,當我需要改用戶 ID 為 13 的文章, 我只需要提交 prid=1 或者 2 那樣我就能繞過去了." 登录 ID 固定为 12,实际上$prids 的值是",12,", 此时你提交 prid=1,在 strpos 里面由于前后被自动拼接了逗号,会变成",1,",显然 strpos(",12,", ",1,") === false 是成立的。没绕过去吧?你觉得你要怎样才能绕过去呢?提交 12 对吧,如果提交 12,确实是绕过去了,但是这种情况和你登录之后在后台进行操作没有区别,程序认为你有权限操作自己的项目和文章,请问有什么问题? |
34
markgor 2019-10-09 18:31:22 +08:00
@rustkeyboard 圖片掛了,你可以看看 book.php?id=8
你查查數據庫這條文字的更新時間和更新記錄吧。 POST:http://idoc.codespeaking.com/admin/api.php did:17 node_type:0 article_content:123" onload="alert(/again/) act:save_article_content prid:32 did->17 是文字的 ID,這個沒問題 prid->32 是我自己伪造的。 ID:17 的這文章並非我添加的,但是我能直接修改刪除,你覺得有問題嗎? |
35
rustkeyboard OP 不好意思,刚刚回复的这一条,有个地方输错了,
登录 ID 固定为 12, 实际上$pids 的值是",12," |
36
markgor 2019-10-09 18:38:57 +08:00
或者我說白點吧,
$pids -> 是 session 中的,我沒理解應為 project_ids 即項目 ID 的意思吧, 添加文章後,數據庫保存了添加的 ID,還有項目的 id(prid) 沒錯吧? 然後修改的時候,通過判斷 提交的 prid 是否包含在 session 中的 pids ,如果包含在裡面的話就執行更新;這裡沒錯吧? 那麼你自己也說,prid 是可以伪造的,既然判斷條件是可以伪造,那你怎麼保證判斷的結果不是伪造的結果呢? 假設: session 中的 pids=32 我直接提交伪造 prid = 32 那這個判斷就已經過去了吧? 然後直接就執行了 undate 或 delete 了。 |
37
rustkeyboard OP @markgor , 这个无需争论,你可以试试通过 api 删除列表里面的第一个项,"大话星程"那本书,你能删掉里面的子节点(书里面的具体章节)或者直接把整本书都删了,再说。
|
38
markgor 2019-10-09 18:45:28 +08:00
@rustkeyboard 已刪
|
39
markgor 2019-10-09 18:47:29 +08:00
header:
Cookie:PHPSESSID=dcfab8f112bb806089dba16dbb109362 POST:XXXX/admin/api.php body: pid:6 act:delete_project prid:32 response: {"status":"SUCC","msg":"\u64cd\u4f5c\u6210\u529f!"} |
40
markgor 2019-10-09 19:12:45 +08:00 via Android
通白点解释就是
两个狼友去按摩, 小明点了个 QT 小强点了个 Kb 老板分配手牌给小明,编号 12 分配手牌给小强,编号 55 然后他们各自进房,小强看到有 JS 经过时候,马上拉她进去,说我手牌是 12, 此时 JS 拿起房间电话打去前台说 12 上钟,前台看到有 12 这个编号,就回复他要做 QT,然后挂了。 小强做完一些嘿嘿嘿的事情后,拿出手牌根据 KB 的价格买单走人了 |
41
rustkeyboard OP @markgor,感谢反馈,已修复。
|
42
lufeng08 2019-10-11 15:44:05 +08:00
|