Skip to content
This repository was archived by the owner on Jul 29, 2020. It is now read-only.

Commit 671af76

Browse files
authored
Merge pull request #81 from MainframeHQ/integration-tests
Integration tests for dev app creation flow, permissions fixes
2 parents b360213 + 833f62c commit 671af76

File tree

15 files changed

+288
-67
lines changed

15 files changed

+288
-67
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ Once your Swarm node is running and you vault settings updated you can publish y
130130
./packages/cli/bin/run app:publishContents --id <APP_ID>
131131
```
132132

133+
If you don't know your app's ID, you can view details of all your apps by running:
134+
135+
```
136+
./packages/cli/bin/run app:list
137+
```
138+
133139
When the upload is complete, you should be presented with a swarm hash, used to identify the location of your contents in the network.
134140

135141
#### 2. Write the App Manifest File

packages/app-permissions/src/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ export const EMPTY_DEFINITIONS: StrictPermissionsDefinitions = {
2222
WEB_REQUEST: [],
2323
}
2424

25+
export const definitionsExist = (
26+
definitions: StrictPermissionsDefinitions,
27+
): boolean => {
28+
if (!definitions) {
29+
return false
30+
}
31+
return Object.keys(definitions).length > 1 || !!definitions.WEB_REQUEST.length
32+
}
33+
34+
export const havePermissionsToGrant = (
35+
requirements: ?StrictPermissionsRequirements,
36+
): boolean => {
37+
if (!requirements) {
38+
return false
39+
}
40+
return (
41+
definitionsExist(requirements.optional) ||
42+
definitionsExist(requirements.required)
43+
)
44+
}
45+
2546
export const createWebRequestGrant = (
2647
granted?: WebRequestDefinition = [],
2748
denied?: WebRequestDefinition = [],

packages/cli/manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":1,"contents":{"version":1,"type":"signed","signed":{"keys":["Bhrta1toa8zb+CAuA+QbunDZGyC6IyBMnl8L4aPM/1k=","YSMwHof04iqgwFg7f80P3ROAW6+/MMmqcFBfyXNkPv8="],"message":"3pDWLtB/fs+//XbUObKRhlmMj5g+OTsKGJ2qyz4LjaMw7Y3fhEwL7CnBUJcN5nNTwlxr8fiZVurPtXQnxItXDvnzo+FSLyJTZj/VQWbHrc8KLnVVKbXV9aNcpBPMVs0VndKVWZ/axTAJW0VWBMpal19rfNb5ppyhwTsZJld9sgt7ImlkIjoidXJuOmVkMjU1MTktcHViLW11bHRpYmFzZTp1QmhydGExdG9hOHpiLUNBdUErUWJ1bkRaR3lDNkl5Qk1ubDhMNGFQTV8xayIsImF1dGhvciI6eyJpZCI6InVybjplZDI1NTE5LXB1Yi1tdWx0aWJhc2U6dVlTTXdIb2YwNGlxZ3dGZzdmODBQM1JPQVc2LV9NTW1xY0ZCZnlYTmtQdjgifSwibmFtZSI6Im1peGVkIiwidmVyc2lvbiI6IjEuMC4wIiwiY29udGVudHNVUkkiOiJ1cm46Ynp6OmIzYzUwMDI1ZTM3NDljNDY0NmZkNzIxM2JiYWFiNjAyY2EyMWIwY2YwOGJhOWVkMWJlYTUyMzZmOGNhMDUzYWEiLCJwZXJtaXNzaW9ucyI6eyJvcHRpb25hbCI6eyJTV0FSTV9ET1dOTE9BRCI6dHJ1ZSwiU1dBUk1fVVBMT0FEIjp0cnVlLCJXRUJfUkVRVUVTVCI6WyJtYWluZnJhbWUuY29tIl19LCJyZXF1aXJlZCI6eyJCTE9DS0NIQUlOX1NFTkQiOnRydWUsIldFQl9SRVFVRVNUIjpbXX19fQ=="}}}

packages/cli/src/commands/app/list.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// @flow
2+
import util from 'util'
3+
4+
import Command from '../../OpenVaultCommand'
5+
6+
export default class AppListCommand extends Command {
7+
static description = `List apps you've created and installed`
8+
static flags = Command.flags
9+
10+
async run() {
11+
// $FlowFixMe: indexer property
12+
const res = await this.client.app.getAll()
13+
Object.keys(res).forEach(type => {
14+
this.log(`\n${type === 'own' ? 'Created' : 'Installed'} Apps\n`)
15+
res[type].forEach(app => {
16+
this.log(`\n ${app.manifest.name}, v${app.manifest.version}\n`)
17+
this.log(' ID:', app.appID)
18+
if (type === 'own') {
19+
this.log(' MainframeID: ', app.manifest.mainframeID)
20+
this.log(' Developer: ', app.manifest.developerID)
21+
this.log(' Contents Path: ', app.manifest.contentsPath)
22+
} else {
23+
this.log(' Author: ', app.manifest.author.id)
24+
this.log(' Contents URI: ', app.manifest.contentsURI)
25+
this.log(' Permissions: ', util.inspect(app.manifest.permissions))
26+
}
27+
this.log(' Users: ', app.users, '\n')
28+
})
29+
})
30+
}
31+
}

packages/cli/src/commands/identity/list.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@ import { prompt } from 'inquirer'
55
import Command from '../../OpenVaultCommand'
66

77
export default class IdentityListCommand extends Command {
8-
static description = 'Manage Identities'
8+
static description = 'List Identities'
99
static flags = Command.flags
1010

1111
async run() {
12-
const client = this.createClient()
13-
if (client == null) {
14-
return
15-
}
1612
const func = await promptSelectCommand()
1713
// $FlowFixMe: indexer property
18-
const res = await client[func]()
14+
const res = await this.client.identity[func]()
1915
Object.keys(res).forEach(type => {
2016
res[type].forEach(identity => {
2117
this.log('\nid: ', identity.id)
@@ -27,8 +23,8 @@ export default class IdentityListCommand extends Command {
2723

2824
const promptSelectCommand = async () => {
2925
const identityListMethods = {
30-
'Own Developers': 'getOwnDeveloperIdentities',
31-
'Own Users': 'getOwnUserIdentities',
26+
'Own Developers': 'getOwnDevelopers',
27+
'Own Users': 'getOwnUsers',
3228
}
3329
const answers = await prompt([
3430
{

packages/daemon/src/app/AbstractApp.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,6 @@ export default class AbstractApp {
112112
}
113113
}
114114

115-
getPermissionsChecked(userID: ID): boolean {
116-
return this.getSettings(userID).permissionsChecked
117-
}
118-
119115
setPermissionsChecked(userID: ID, checked: boolean) {
120116
const settings = this.getSettings(userID)
121117
settings.permissionsChecked = checked

packages/daemon/src/app/App.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import type { ManifestData } from '@mainframe/app-manifest'
44
import {
55
createWebRequestGrant,
6+
havePermissionsToGrant,
67
mergeGrantsToDetails,
78
PERMISSION_KEYS_BOOLEAN,
89
type StrictPermissionsGrants,
@@ -65,6 +66,13 @@ export default class App extends AbstractApp {
6566
return this._manifest
6667
}
6768

69+
getPermissionsChecked(userID: ID): boolean {
70+
if (!havePermissionsToGrant(this._manifest.permissions)) {
71+
return true
72+
}
73+
return this.getSettings(userID).permissionsChecked
74+
}
75+
6876
// Session
6977

7078
createSession(userID: ID): SessionData {

packages/daemon/src/rpc/methods/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export const getAll = (ctx: RequestContext): AppGetAllResult => {
146146
acc.push({
147147
id: toClientID(id),
148148
data: user.data,
149+
settings: app.getSettings(id),
149150
})
150151
}
151152
return acc

packages/launcher/src/renderer/launcher/AppInstallModal.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
//@flow
22

3-
import type { PermissionsGrants } from '@mainframe/app-permissions'
3+
import {
4+
havePermissionsToGrant,
5+
type StrictPermissionsGrants,
6+
createStrictPermissionGrants,
7+
} from '@mainframe/app-permissions'
48
import type { ID } from '@mainframe/client'
9+
import type { ManifestData } from '@mainframe/app-manifest'
510
import React, { createRef, Component, type ElementRef } from 'react'
611
import { View, StyleSheet } from 'react-native-web'
712

@@ -10,7 +15,7 @@ import Text from '../UIComponents/Text'
1015
import ModalView from '../UIComponents/ModalView'
1116

1217
import rpc from './rpc'
13-
import PermissionsView, { type PermissionOptions } from './PermissionsView'
18+
import PermissionsView from './PermissionsView'
1419
import IdentitySelectorView from './IdentitySelectorView'
1520

1621
type Props = {
@@ -27,11 +32,8 @@ type User = {
2732
type State = {
2833
inputValue: string,
2934
installStep: 'manifest' | 'identity' | 'permissions' | 'download',
30-
manifest: ?{
31-
name: string,
32-
permissions: PermissionOptions,
33-
},
34-
userPermissions?: PermissionsGrants,
35+
manifest: ?ManifestData,
36+
userPermissions?: StrictPermissionsGrants,
3537
userId?: ID,
3638
ownUsers: Array<User>,
3739
}
@@ -85,7 +87,7 @@ export default class AppInstallModal extends Component<Props, State> {
8587
}
8688
}
8789

88-
onSubmitPermissions = (userPermissions: PermissionsGrants) => {
90+
onSubmitPermissions = (userPermissions: StrictPermissionsGrants) => {
8991
this.setState(
9092
{
9193
installStep: 'download',
@@ -107,7 +109,21 @@ export default class AppInstallModal extends Component<Props, State> {
107109
}
108110

109111
onSelectId = (id: ID) => {
110-
this.setState({ installStep: 'permissions', userId: id })
112+
const { manifest } = this.state
113+
if (
114+
manifest &&
115+
manifest.permissions &&
116+
havePermissionsToGrant(manifest.permissions)
117+
) {
118+
this.setState({
119+
installStep: 'permissions',
120+
userId: id,
121+
})
122+
} else {
123+
this.setState({ userId: id })
124+
const strictGrants = createStrictPermissionGrants({})
125+
this.onSubmitPermissions(strictGrants)
126+
}
111127
}
112128

113129
onCreatedId = () => {

packages/launcher/src/renderer/launcher/IdentitySelectorView.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Props = {
2828
identities: Array<Identity>,
2929
enableCreate?: boolean,
3030
onSelectId: (id: ID) => any,
31-
onCreatedId?: (id: ID) => void,
31+
onCreatedId?: (id: ID) => any,
3232
}
3333

3434
type State = {
@@ -47,7 +47,7 @@ export default class IdentitySelectorView extends Component<Props, State> {
4747
this.createId()
4848
}
4949

50-
async createId() {
50+
createId = async () => {
5151
try {
5252
let createIdentity
5353
switch (this.props.type) {

0 commit comments

Comments
 (0)