Skip to content

Commit 9258fec

Browse files
committed
mobx: Created addSessionView, added support for custom sessions
1 parent b826051 commit 9258fec

File tree

4 files changed

+259
-2
lines changed

4 files changed

+259
-2
lines changed

app/src/store/store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from './stores';
2121
import {
2222
AccountSectionView,
23+
AddSessionView,
2324
AppView,
2425
BatchesView,
2526
BuildSwapView,
@@ -66,6 +67,7 @@ export class Store {
6667
orderListView = new OrderListView(this);
6768
batchesView = new BatchesView(this);
6869
registerSidecarView = new RegisterSidecarView(this);
70+
addSessionView = new AddSessionView(this);
6971

7072
/** the backend api services to be used by child stores */
7173
api: {

app/src/store/stores/sessionStore.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ export default class SessionStore {
102102
type: LIT.SessionTypeMap[keyof LIT.SessionTypeMap],
103103
expiry: Date,
104104
copy = false,
105+
proxy?: string,
106+
customPermissions?: LIT.MacaroonPermission[],
105107
) {
106108
try {
107109
this._store.log.info(`submitting session with label ${label}`, {
@@ -114,9 +116,9 @@ export default class SessionStore {
114116
label,
115117
type,
116118
expiry,
117-
this.proxyServer,
119+
proxy || this.proxyServer,
118120
!IS_PROD,
119-
[],
121+
customPermissions || [],
120122
);
121123

122124
// fetch all sessions to update the store's state

app/src/store/views/addSessionView.ts

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import { makeAutoObservable, observable } from 'mobx';
2+
import { Store } from 'store';
3+
import * as LIT from 'types/generated/lit-sessions_pb';
4+
import { MAX_DATE } from 'util/constants';
5+
6+
export default class AddSessionView {
7+
private _store: Store;
8+
9+
// A map of all the necessary URIs for each set of features
10+
private permissionMap: { [key: string]: string[] } = {
11+
openChannel: [
12+
'/lnrpc.Lightning/OpenChannel',
13+
'/lnrpc.Lightning/BatchOpenChannel',
14+
'/lnrpc.Lightning/OpenChannelSync',
15+
],
16+
closeChannel: ['/lnrpc.Lightning/CloseChannel'],
17+
setFees: [
18+
'/lnrpc.Lightning/EstimateFee',
19+
'/lnrpc.Lightning/FeeReport',
20+
'/lnrpc.Lightning/UpdateChannelPolicy',
21+
],
22+
loop: ['^/looprpc\\.SwapClient/.*$'],
23+
pool: ['^/poolrpc\\.Trader/.*$'],
24+
send: [
25+
'/lnrpc.Lightning/SendCoins',
26+
'/lnrpc.Lightning/SendMany',
27+
'/lnrpc.Lightning/SendPayment',
28+
'/lnrpc.Lightning/SendPaymentSync',
29+
'/lnrpc.Lightning/SendToRoute',
30+
'/lnrpc.Lightning/SendToRouteSync',
31+
],
32+
receive: [
33+
'/lnrpc.Lightning/NewAddress',
34+
'/lnrpc.Lightning/AddInvoice',
35+
'/lnrpc.Lightning/LookupInvoice',
36+
'/lnrpc.Lightning/ListInvoices',
37+
'/lnrpc.Lightning/SubscribeInvoices',
38+
],
39+
};
40+
41+
label = '';
42+
permissionType = 'admin';
43+
editing = false;
44+
permissions: { [key: string]: boolean } = {
45+
openChannel: false,
46+
closeChannel: false,
47+
setFees: false,
48+
loop: false,
49+
pool: false,
50+
send: false,
51+
receive: false,
52+
};
53+
expiration = 'never';
54+
expirationDate = '';
55+
showAdvanced = false;
56+
proxy = '';
57+
58+
constructor(store: Store) {
59+
makeAutoObservable(
60+
this,
61+
{
62+
permissions: observable.deep,
63+
},
64+
{ deep: false, autoBind: true },
65+
);
66+
67+
this._store = store;
68+
}
69+
70+
//
71+
// Private helper functions
72+
//
73+
74+
private setAllPermissions(value: boolean) {
75+
Object.keys(this.permissions).forEach(permissionName => {
76+
this.permissions[permissionName] = value;
77+
});
78+
}
79+
80+
private getMacaroonPermissions() {
81+
// Only output macaroon permissions when the session type is custom
82+
if (this.sessionType === LIT.SessionType.TYPE_MACAROON_CUSTOM) {
83+
// Include all read-only URIs by default
84+
const permissions: string[] = ['***readonly***'];
85+
86+
// Loop over all permissions to determine which are enabled
87+
Object.entries(this.permissions).forEach(([permissionName, permissionEnabled]) => {
88+
if (permissionEnabled) {
89+
// Add all of the URIs for this permission
90+
permissions.push(...this.permissionMap[permissionName]);
91+
}
92+
});
93+
94+
// Convert all of the permission strings into MacaroonPermission objects
95+
return permissions.map(uri => {
96+
const mp = new LIT.MacaroonPermission();
97+
mp.setEntity('uri');
98+
mp.setAction(uri);
99+
return mp;
100+
});
101+
}
102+
103+
return [];
104+
}
105+
106+
//
107+
// Computed properties
108+
//
109+
110+
get sessionType() {
111+
if (this.permissionType === 'admin') {
112+
return LIT.SessionType.TYPE_MACAROON_ADMIN;
113+
} else if (this.permissionType === 'read-only') {
114+
return LIT.SessionType.TYPE_MACAROON_READONLY;
115+
}
116+
117+
return LIT.SessionType.TYPE_MACAROON_CUSTOM;
118+
}
119+
120+
get sessionDate() {
121+
// If the expiration date is a number of days
122+
if (Number.isInteger(parseInt(this.expiration))) {
123+
const expirationDate = new Date();
124+
expirationDate.setDate(expirationDate.getDate() + parseInt(this.expiration));
125+
return expirationDate;
126+
} else if (this.expiration === 'custom') {
127+
return new Date(this.expirationDate);
128+
}
129+
130+
// Default to max date for when the expiration is "never"
131+
return MAX_DATE;
132+
}
133+
134+
get sessionProxy() {
135+
if (this.proxy) {
136+
return this.proxy;
137+
}
138+
139+
return undefined;
140+
}
141+
142+
//
143+
// Actions
144+
//
145+
146+
setLabel(label: string) {
147+
this.label = label;
148+
}
149+
150+
setExpiration(expiration: string) {
151+
this.expiration = expiration;
152+
}
153+
154+
setExpirationDate(expirationDate: string) {
155+
this.expirationDate = expirationDate;
156+
}
157+
158+
setProxy(proxy: string) {
159+
this.proxy = proxy;
160+
}
161+
162+
setPermissionType(permissionType: string) {
163+
this.permissionType = permissionType;
164+
165+
switch (permissionType) {
166+
case 'admin':
167+
this.setAllPermissions(true);
168+
break;
169+
170+
case 'read-only':
171+
this.setAllPermissions(false);
172+
break;
173+
174+
case 'liquidity':
175+
this.setAllPermissions(false);
176+
this.permissions.setFees = true;
177+
this.permissions.loop = true;
178+
this.permissions.pool = true;
179+
break;
180+
181+
case 'payments':
182+
this.setAllPermissions(false);
183+
this.permissions.send = true;
184+
this.permissions.receive = true;
185+
break;
186+
187+
case 'custom':
188+
// We don't need to change anything, let the user customize permissions how they want
189+
break;
190+
}
191+
}
192+
193+
togglePermission(permission: string) {
194+
this.setPermissionType('custom');
195+
this.permissions[permission] = !this.permissions[permission];
196+
}
197+
198+
toggleEditing() {
199+
this.editing = !this.editing;
200+
}
201+
202+
toggleAdvanced() {
203+
this.showAdvanced = !this.showAdvanced;
204+
}
205+
206+
cancel() {
207+
this.label = '';
208+
this.permissionType = 'admin';
209+
this.editing = false;
210+
this.setAllPermissions(false);
211+
this.expiration = 'never';
212+
this.showAdvanced = false;
213+
}
214+
215+
//
216+
// Async Actions
217+
//
218+
219+
async handleSubmit() {
220+
if (this.permissionType === 'custom') {
221+
this._store.settingsStore.sidebarVisible = false;
222+
this._store.router.push('/connect/custom');
223+
} else {
224+
const session = await this._store.sessionStore.addSession(
225+
this.label,
226+
this.sessionType,
227+
MAX_DATE,
228+
true,
229+
);
230+
231+
if (session) {
232+
this.cancel();
233+
}
234+
}
235+
}
236+
237+
async handleCustomSubmit() {
238+
const session = await this._store.sessionStore.addSession(
239+
this.label,
240+
this.sessionType,
241+
this.sessionDate,
242+
true,
243+
this.sessionProxy,
244+
this.getMacaroonPermissions(),
245+
);
246+
247+
if (session) {
248+
this.cancel();
249+
this._store.router.push('/connect');
250+
}
251+
}
252+
}

app/src/store/views/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export { default as OrderListView } from './orderListView';
1010
export { default as LeaseView } from './leaseView';
1111
export { default as BatchesView } from './batchesView';
1212
export { default as RegisterSidecarView } from './registerSidecarView';
13+
export { default as AddSessionView } from './addSessionView';

0 commit comments

Comments
 (0)