fs 0.0.1
[henge/kiak.git] / src / strapp.js
1 /**
2 * @file Strapp main driver
3 * @author Jordan Lavatai, Ken Grimes
4 * @version 0.0.4
5 * @license AGPL-3.0
6 * @copyright August 2017 - Ken Grimes, Jordan Lavatai
7 * @summmary Bootstrapper for the strapp.io mechanism
8 */
9 import LocalForage from "localforage"
10
11 const StrappFile = (() => {
12 const localforage = LocalForage.createInstance({
13 driver: [LocalForage.LOCALSTORAGE,
14 LocalForage.INDEXEDDB,
15 LocalForage.WEBSQL],
16 name: 'strapp',
17 version: 0.1,
18 storeName: 'strapp'
19 })
20 const authorize = (pubKey, mode, stat) => {
21 let allowed
22 if (pubKey === stat.owner)
23 allowed = (stat.perms >>> 16) & 0xF
24 else {
25 let gAccess = false
26 let uGroups = StrappFile.get(`acct/${pubKey}/groups`).split(' ')
27 for (let i = 0; i < uGroups.length; i++) {
28 if (uGroups[i] === stat.group) {
29 gAccess = true
30 break
31 }
32 }
33 if (gAccess)
34 allowed = (stat.perms >>> 8) & 0xF
35 else
36 allowed = stat.perms & 0xF
37 }
38 switch(mode){
39 case 'r+':
40 case 'rw':
41 case 'wr':
42 return (allowed & 0x6) === 0x6
43 case 'w':
44 return (allowed & 0x2) === 0x2
45 case 'r':
46 return (allowed & 0x4) === 0x4
47 case 'x':
48 return (allowed & 0x1) === 0x1
49 default:
50 console.log(`Unknown access mode: ${mode}`)
51 return false
52 }
53 }
54 class StrappFile extends Object {
55 constructor(...props) {
56 super()
57 return Object.assign(this, new.target.defaults, ...props)
58 }
59 static PermissionDenied() {
60 return new Promise((resolve, reject) => reject('Permission denied'))
61 }
62 static get(path) {
63 return localforage.getItem(path)
64 }
65 static set(path, data) {
66 return localforage.setItem(path, data)
67 }
68 static delete(path) {
69 return localforage.removeItem(path)
70 }
71 HEAD(opt) {
72 if (authorize(opt.pubKey, 'r', this.stat))
73 return new Promise((resolve, reject) => resolve(''))
74 else
75 return StrappFile.PermissionDenied()
76 }
77 GET(opt) {
78 if (authorize(opt.pubKey, 'r', this.stat))
79 return StrappFile.get(this.path)
80 else return StrappFile.PermissionDenied()
81 }
82 PUT(opt) {
83 if (authorize(opt.pubKey, 'w', this.stat))
84 return StrappFile.set(this.path, opt.data)
85 else return StrappFile.PermissionDenied()
86 }
87 POST(opt) {
88 return this.PUT(Object.assign(opt, { data: this.GET(opt) + opt.data }))
89 }
90 DELETE(opt) {
91 if (authorize(opt.pubKey, 'w', this.stat))
92 return StrappFile.delete(this.path)
93 else return StrappFile.PermissionDenied()
94 }
95 OPTIONS(opt) {
96 return this.stat
97 }
98 CONNECT(opt) {
99 return this.GET(opt)
100 }
101 TRACE(opt) {
102 }
103 PATCH(opt) {
104 }
105 }
106 StrappFile.defaults = {
107 stat: {
108 type: 'mime/type',
109 perm: 0,
110 owner: 'thisOwnerPubKey',
111 group: 'groupname',
112 changed: 'time',
113 created: 'time',
114 accessed: 'time - not saved'
115 }
116 }
117 return StrappFile
118 })()
119
120 const StrappPeerConnection = (() => {
121 class StrappPeerConnection extends StrappFile {
122 GET(opts) {
123 //get metadata (held in filesystem), with owner, usage info, etc
124 //if unauthed, send message down socket
125 }
126 PUT(opts) {
127 //create w/ sdp, register callback (or pipe), set owner
128 }
129 POST(opts) {
130 //send msg
131 }
132 CONNECT(opts) {
133 //send routing message down socket
134 //POST(opts.routemessage)
135 }
136 }
137 return StrappPeerConnection
138 })()
139
140 const StrappDirectory = (() => {
141 class StrappDirectory extends StrappFile {
142 }
143 return StrappDirectory
144 })()
145
146
147
148 export default StrappFile
149 export { StrappPeerConnection, StrappDirectory }