|
|
|
import { strict as assert } from 'assert'
|
|
|
|
import sinon from 'sinon'
|
|
|
|
|
|
|
|
import {
|
|
|
|
METADATA_STORE_KEY,
|
|
|
|
} from '../../../../../app/scripts/controllers/permissions/enums'
|
|
|
|
|
|
|
|
import {
|
|
|
|
PermissionsController,
|
|
|
|
} from '../../../../../app/scripts/controllers/permissions'
|
|
|
|
|
|
|
|
import {
|
|
|
|
getUserApprovalPromise,
|
|
|
|
grantPermissions,
|
|
|
|
} from './helpers'
|
|
|
|
|
|
|
|
import {
|
|
|
|
constants,
|
|
|
|
getters,
|
|
|
|
getPermControllerOpts,
|
|
|
|
getPermissionsMiddleware,
|
|
|
|
} from './mocks'
|
|
|
|
|
|
|
|
const {
|
|
|
|
CAVEATS,
|
|
|
|
ERRORS,
|
|
|
|
PERMS,
|
|
|
|
RPC_REQUESTS,
|
|
|
|
} = getters
|
|
|
|
|
|
|
|
const {
|
|
|
|
ACCOUNTS,
|
|
|
|
DOMAINS,
|
|
|
|
PERM_NAMES,
|
|
|
|
} = constants
|
|
|
|
|
|
|
|
const validatePermission = (perm, name, origin, caveats) => {
|
|
|
|
assert.equal(name, perm.parentCapability, 'should have expected permission name')
|
|
|
|
assert.equal(origin, perm.invoker, 'should have expected permission origin')
|
|
|
|
if (caveats) {
|
|
|
|
assert.deepEqual(caveats, perm.caveats, 'should have expected permission caveats')
|
|
|
|
} else {
|
|
|
|
assert.ok(!perm.caveats, 'should not have any caveats')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const initPermController = () => {
|
|
|
|
return new PermissionsController({
|
|
|
|
...getPermControllerOpts(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('permissions middleware', function () {
|
|
|
|
|
|
|
|
describe('wallet_requestPermissions', function () {
|
|
|
|
|
|
|
|
let permController
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
permController = initPermController()
|
|
|
|
permController.notifyAccountsChanged = sinon.fake()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('grants permissions on user approval', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.requestPermission(
|
|
|
|
DOMAINS.a.origin, PERM_NAMES.eth_accounts,
|
|
|
|
)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
const pendingApproval = assert.doesNotReject(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
'should not reject permissions request',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 1,
|
|
|
|
'perm controller should have single pending approval',
|
|
|
|
)
|
|
|
|
|
|
|
|
const id = permController.pendingApprovals.keys().next().value
|
|
|
|
const approvedReq = PERMS.approvedRequest(id, PERMS.requests.eth_accounts())
|
|
|
|
|
|
|
|
await permController.approvePermissionsRequest(approvedReq, ACCOUNTS.a.permitted)
|
|
|
|
await pendingApproval
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res.result && !res.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
res.result.length, 1,
|
|
|
|
'origin should have single approved permission',
|
|
|
|
)
|
|
|
|
|
|
|
|
validatePermission(
|
|
|
|
res.result[0],
|
|
|
|
PERM_NAMES.eth_accounts,
|
|
|
|
DOMAINS.a.origin,
|
|
|
|
CAVEATS.eth_accounts(ACCOUNTS.a.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
const aAccounts = await permController.getAccounts(DOMAINS.a.origin)
|
|
|
|
assert.deepEqual(
|
|
|
|
aAccounts, [ACCOUNTS.a.primary],
|
|
|
|
'origin should have correct accounts',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
permController.notifyAccountsChanged.calledOnceWith(
|
|
|
|
DOMAINS.a.origin, aAccounts,
|
|
|
|
),
|
|
|
|
'expected notification call should have been made',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('handles serial approved requests that overwrite existing permissions', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
// create first request
|
|
|
|
|
|
|
|
const req1 = RPC_REQUESTS.requestPermission(
|
|
|
|
DOMAINS.a.origin, PERM_NAMES.eth_accounts,
|
|
|
|
)
|
|
|
|
const res1 = {}
|
|
|
|
|
|
|
|
// send, approve, and validate first request
|
|
|
|
// note use of ACCOUNTS.a.permitted
|
|
|
|
|
|
|
|
const pendingApproval1 = assert.doesNotReject(
|
|
|
|
aMiddleware(req1, res1),
|
|
|
|
'should not reject permissions request',
|
|
|
|
)
|
|
|
|
|
|
|
|
const id1 = permController.pendingApprovals.keys().next().value
|
|
|
|
const approvedReq1 = PERMS.approvedRequest(id1, PERMS.requests.eth_accounts())
|
|
|
|
|
|
|
|
await permController.approvePermissionsRequest(approvedReq1, ACCOUNTS.a.permitted)
|
|
|
|
await pendingApproval1
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res1.result && !res1.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
res1.result.length, 1,
|
|
|
|
'origin should have single approved permission',
|
|
|
|
)
|
|
|
|
|
|
|
|
validatePermission(
|
|
|
|
res1.result[0],
|
|
|
|
PERM_NAMES.eth_accounts,
|
|
|
|
DOMAINS.a.origin,
|
|
|
|
CAVEATS.eth_accounts(ACCOUNTS.a.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
const accounts1 = await permController.getAccounts(DOMAINS.a.origin)
|
|
|
|
assert.deepEqual(
|
|
|
|
accounts1, [ACCOUNTS.a.primary],
|
|
|
|
'origin should have correct accounts',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
permController.notifyAccountsChanged.calledOnceWith(
|
|
|
|
DOMAINS.a.origin, accounts1,
|
|
|
|
),
|
|
|
|
'expected notification call should have been made',
|
|
|
|
)
|
|
|
|
|
|
|
|
// create second request
|
|
|
|
|
|
|
|
const requestedPerms2 = {
|
|
|
|
...PERMS.requests.eth_accounts(),
|
|
|
|
...PERMS.requests.test_method(),
|
|
|
|
}
|
|
|
|
|
|
|
|
const req2 = RPC_REQUESTS.requestPermissions(
|
|
|
|
DOMAINS.a.origin, { ...requestedPerms2 },
|
|
|
|
)
|
|
|
|
const res2 = {}
|
|
|
|
|
|
|
|
// send, approve, and validate second request
|
|
|
|
// note use of ACCOUNTS.b.permitted
|
|
|
|
|
|
|
|
const pendingApproval2 = assert.doesNotReject(
|
|
|
|
aMiddleware(req2, res2),
|
|
|
|
'should not reject permissions request',
|
|
|
|
)
|
|
|
|
|
|
|
|
const id2 = permController.pendingApprovals.keys().next().value
|
|
|
|
const approvedReq2 = PERMS.approvedRequest(id2, { ...requestedPerms2 })
|
|
|
|
|
|
|
|
await permController.approvePermissionsRequest(approvedReq2, ACCOUNTS.b.permitted)
|
|
|
|
await pendingApproval2
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res2.result && !res2.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
res2.result.length, 2,
|
|
|
|
'origin should have single approved permission',
|
|
|
|
)
|
|
|
|
|
|
|
|
validatePermission(
|
|
|
|
res2.result[0],
|
|
|
|
PERM_NAMES.eth_accounts,
|
|
|
|
DOMAINS.a.origin,
|
|
|
|
CAVEATS.eth_accounts(ACCOUNTS.b.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
validatePermission(
|
|
|
|
res2.result[1],
|
|
|
|
PERM_NAMES.test_method,
|
|
|
|
DOMAINS.a.origin,
|
|
|
|
)
|
|
|
|
|
|
|
|
const accounts2 = await permController.getAccounts(DOMAINS.a.origin)
|
|
|
|
assert.deepEqual(
|
|
|
|
accounts2, [ACCOUNTS.b.primary],
|
|
|
|
'origin should have correct accounts',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.notifyAccountsChanged.callCount, 2,
|
|
|
|
'should have called notification method 2 times in total',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
permController.notifyAccountsChanged.lastCall.calledWith(
|
|
|
|
DOMAINS.a.origin, accounts2,
|
|
|
|
),
|
|
|
|
'expected notification call should have been made',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('rejects permissions on user rejection', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.requestPermission(
|
|
|
|
DOMAINS.a.origin, PERM_NAMES.eth_accounts,
|
|
|
|
)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
const expectedError = ERRORS.rejectPermissionsRequest.rejection()
|
|
|
|
|
|
|
|
const requestRejection = assert.rejects(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
expectedError,
|
|
|
|
'request should be rejected with correct error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 1,
|
|
|
|
'perm controller should have single pending approval',
|
|
|
|
)
|
|
|
|
|
|
|
|
const id = permController.pendingApprovals.keys().next().value
|
|
|
|
|
|
|
|
await permController.rejectPermissionsRequest(id)
|
|
|
|
await requestRejection
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
(
|
|
|
|
!res.result && res.error &&
|
|
|
|
res.error.message === expectedError.message
|
|
|
|
),
|
|
|
|
'response should have expected error and no result',
|
|
|
|
)
|
|
|
|
|
|
|
|
const aAccounts = await permController.getAccounts(DOMAINS.a.origin)
|
|
|
|
assert.deepEqual(
|
|
|
|
aAccounts, [], 'origin should have have correct accounts',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
permController.notifyAccountsChanged.notCalled,
|
|
|
|
'should not have called notification method',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('rejects requests with unknown permissions', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.requestPermissions(
|
|
|
|
DOMAINS.a.origin, {
|
|
|
|
...PERMS.requests.does_not_exist(),
|
|
|
|
...PERMS.requests.test_method(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
const expectedError = ERRORS.rejectPermissionsRequest.methodNotFound(
|
|
|
|
PERM_NAMES.does_not_exist,
|
|
|
|
)
|
|
|
|
|
|
|
|
await assert.rejects(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
expectedError,
|
|
|
|
'request should be rejected with correct error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 0,
|
|
|
|
'perm controller should have no pending approvals',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
(
|
|
|
|
!res.result && res.error &&
|
|
|
|
res.error.message === expectedError.message
|
|
|
|
),
|
|
|
|
'response should have expected error and no result',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
permController.notifyAccountsChanged.notCalled,
|
|
|
|
'should not have called notification method',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('accepts only a single pending permissions request per origin', async function () {
|
|
|
|
|
|
|
|
const expectedError = ERRORS.pendingApprovals.requestAlreadyPending()
|
|
|
|
|
|
|
|
// two middlewares for two origins
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
const bMiddleware = getPermissionsMiddleware(permController, DOMAINS.b.origin)
|
|
|
|
|
|
|
|
// create and start processing first request for first origin
|
|
|
|
|
|
|
|
const reqA1 = RPC_REQUESTS.requestPermission(
|
|
|
|
DOMAINS.a.origin, PERM_NAMES.test_method,
|
|
|
|
)
|
|
|
|
const resA1 = {}
|
|
|
|
|
|
|
|
const requestApproval1 = assert.doesNotReject(
|
|
|
|
aMiddleware(reqA1, resA1),
|
|
|
|
'should not reject permissions request',
|
|
|
|
)
|
|
|
|
|
|
|
|
// create and start processing first request for second origin
|
|
|
|
|
|
|
|
const reqB1 = RPC_REQUESTS.requestPermission(
|
|
|
|
DOMAINS.b.origin, PERM_NAMES.test_method,
|
|
|
|
)
|
|
|
|
const resB1 = {}
|
|
|
|
|
|
|
|
const requestApproval2 = assert.doesNotReject(
|
|
|
|
bMiddleware(reqB1, resB1),
|
|
|
|
'should not reject permissions request',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 2,
|
|
|
|
'perm controller should have expected number of pending approvals',
|
|
|
|
)
|
|
|
|
|
|
|
|
// create and start processing second request for first origin,
|
|
|
|
// which should throw
|
|
|
|
|
|
|
|
const reqA2 = RPC_REQUESTS.requestPermission(
|
|
|
|
DOMAINS.a.origin, PERM_NAMES.test_method,
|
|
|
|
)
|
|
|
|
const resA2 = {}
|
|
|
|
|
|
|
|
await assert.rejects(
|
|
|
|
aMiddleware(reqA2, resA2),
|
|
|
|
expectedError,
|
|
|
|
'request should be rejected with correct error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
(
|
|
|
|
!resA2.result && resA2.error &&
|
|
|
|
resA2.error.message === expectedError.message
|
|
|
|
),
|
|
|
|
'response should have expected error and no result',
|
|
|
|
)
|
|
|
|
|
|
|
|
// first requests for both origins should remain
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 2,
|
|
|
|
'perm controller should have expected number of pending approvals',
|
|
|
|
)
|
|
|
|
|
|
|
|
// now, remaining pending requests should be approved without issue
|
|
|
|
|
|
|
|
for (const id of permController.pendingApprovals.keys()) {
|
|
|
|
await permController.approvePermissionsRequest(
|
|
|
|
PERMS.approvedRequest(id, PERMS.requests.test_method()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
await requestApproval1
|
|
|
|
await requestApproval2
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
resA1.result && !resA1.error,
|
|
|
|
'first response should have result and no error',
|
|
|
|
)
|
|
|
|
assert.equal(
|
|
|
|
resA1.result.length, 1,
|
|
|
|
'first origin should have single approved permission',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
resB1.result && !resB1.error,
|
|
|
|
'second response should have result and no error',
|
|
|
|
)
|
|
|
|
assert.equal(
|
|
|
|
resB1.result.length, 1,
|
|
|
|
'second origin should have single approved permission',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 0,
|
|
|
|
'perm controller should have expected number of pending approvals',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('restricted methods', function () {
|
|
|
|
|
|
|
|
let permController
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
permController = initPermController()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('prevents restricted method access for unpermitted domain', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.test_method(DOMAINS.a.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
const expectedError = ERRORS.rpcCap.unauthorized()
|
|
|
|
|
|
|
|
await assert.rejects(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
expectedError,
|
|
|
|
'request should be rejected with correct error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
(
|
|
|
|
!res.result && res.error &&
|
|
|
|
res.error.code === expectedError.code
|
|
|
|
),
|
|
|
|
'response should have expected error and no result',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows restricted method access for permitted domain', async function () {
|
|
|
|
|
|
|
|
const bMiddleware = getPermissionsMiddleware(permController, DOMAINS.b.origin)
|
|
|
|
|
|
|
|
grantPermissions(permController, DOMAINS.b.origin, PERMS.finalizedRequests.test_method())
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.test_method(DOMAINS.b.origin, true)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
bMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res.result && res.result === 1,
|
|
|
|
'response should have correct result',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('eth_accounts', function () {
|
|
|
|
|
|
|
|
let permController
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
permController = initPermController()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('returns empty array for non-permitted domain', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.eth_accounts(DOMAINS.a.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res.result && !res.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
assert.deepEqual(
|
|
|
|
res.result, [],
|
|
|
|
'response should have correct result',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('returns correct accounts for permitted domain', async function () {
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
grantPermissions(
|
|
|
|
permController, DOMAINS.a.origin,
|
|
|
|
PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.eth_accounts(DOMAINS.a.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res.result && !res.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
assert.deepEqual(
|
|
|
|
res.result, [ACCOUNTS.a.primary],
|
|
|
|
'response should have correct result',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('eth_requestAccounts', function () {
|
|
|
|
|
|
|
|
let permController
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
permController = initPermController()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('requests accounts for unpermitted origin, and approves on user approval', async function () {
|
|
|
|
|
|
|
|
const userApprovalPromise = getUserApprovalPromise(permController)
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.a.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
const pendingApproval = assert.doesNotReject(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
'should not reject permissions request',
|
|
|
|
)
|
|
|
|
|
|
|
|
await userApprovalPromise
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 1,
|
|
|
|
'perm controller should have single pending approval',
|
|
|
|
)
|
|
|
|
|
|
|
|
const id = permController.pendingApprovals.keys().next().value
|
|
|
|
const approvedReq = PERMS.approvedRequest(id, PERMS.requests.eth_accounts())
|
|
|
|
|
|
|
|
await permController.approvePermissionsRequest(approvedReq, ACCOUNTS.a.permitted)
|
|
|
|
|
|
|
|
// wait for permission to be granted
|
|
|
|
await pendingApproval
|
|
|
|
|
|
|
|
const perms = permController.permissions.getPermissionsForDomain(DOMAINS.a.origin)
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
perms.length, 1,
|
|
|
|
'domain should have correct number of permissions',
|
|
|
|
)
|
|
|
|
|
|
|
|
validatePermission(
|
|
|
|
perms[0],
|
|
|
|
PERM_NAMES.eth_accounts,
|
|
|
|
DOMAINS.a.origin,
|
|
|
|
CAVEATS.eth_accounts(ACCOUNTS.a.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
// we should also see the accounts on the response
|
|
|
|
assert.ok(
|
|
|
|
res.result && !res.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.deepEqual(
|
|
|
|
res.result, [ACCOUNTS.a.primary],
|
|
|
|
'result should have correct accounts',
|
|
|
|
)
|
|
|
|
|
|
|
|
// we should also be able to get the accounts independently
|
|
|
|
const aAccounts = await permController.getAccounts(DOMAINS.a.origin)
|
|
|
|
assert.deepEqual(
|
|
|
|
aAccounts, [ACCOUNTS.a.primary], 'origin should have have correct accounts',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('requests accounts for unpermitted origin, and rejects on user rejection', async function () {
|
|
|
|
|
|
|
|
const userApprovalPromise = getUserApprovalPromise(permController)
|
|
|
|
|
|
|
|
const aMiddleware = getPermissionsMiddleware(permController, DOMAINS.a.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.a.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
const expectedError = ERRORS.rejectPermissionsRequest.rejection()
|
|
|
|
|
|
|
|
const requestRejection = assert.rejects(
|
|
|
|
aMiddleware(req, res),
|
|
|
|
expectedError,
|
|
|
|
'request should be rejected with correct error',
|
|
|
|
)
|
|
|
|
|
|
|
|
await userApprovalPromise
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
permController.pendingApprovals.size, 1,
|
|
|
|
'perm controller should have single pending approval',
|
|
|
|
)
|
|
|
|
|
|
|
|
const id = permController.pendingApprovals.keys().next().value
|
|
|
|
|
|
|
|
await permController.rejectPermissionsRequest(id)
|
|
|
|
await requestRejection
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
(
|
|
|
|
!res.result && res.error &&
|
|
|
|
res.error.message === expectedError.message
|
|
|
|
),
|
|
|
|
'response should have expected error and no result',
|
|
|
|
)
|
|
|
|
|
|
|
|
const aAccounts = await permController.getAccounts(DOMAINS.a.origin)
|
|
|
|
assert.deepEqual(
|
|
|
|
aAccounts, [], 'origin should have have correct accounts',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('directly returns accounts for permitted domain', async function () {
|
|
|
|
|
|
|
|
const cMiddleware = getPermissionsMiddleware(permController, DOMAINS.c.origin)
|
|
|
|
|
|
|
|
grantPermissions(
|
|
|
|
permController, DOMAINS.c.origin,
|
|
|
|
PERMS.finalizedRequests.eth_accounts(ACCOUNTS.c.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
cMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res.result && !res.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
assert.deepEqual(
|
|
|
|
res.result, [ACCOUNTS.c.primary],
|
|
|
|
'response should have correct result',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('rejects new requests when request already pending', async function () {
|
|
|
|
|
|
|
|
let unlock
|
|
|
|
const unlockPromise = new Promise((resolve) => {
|
|
|
|
unlock = resolve
|
|
|
|
})
|
|
|
|
|
|
|
|
permController.getUnlockPromise = () => unlockPromise
|
|
|
|
|
|
|
|
const cMiddleware = getPermissionsMiddleware(permController, DOMAINS.c.origin)
|
|
|
|
|
|
|
|
grantPermissions(
|
|
|
|
permController, DOMAINS.c.origin,
|
|
|
|
PERMS.finalizedRequests.eth_accounts(ACCOUNTS.c.permitted),
|
|
|
|
)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
// this will block until we resolve the unlock Promise
|
|
|
|
const requestApproval = assert.doesNotReject(
|
|
|
|
cMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
// this will reject because of the already pending request
|
|
|
|
await assert.rejects(
|
|
|
|
cMiddleware({ ...req }, {}),
|
|
|
|
ERRORS.eth_requestAccounts.requestAlreadyPending(),
|
|
|
|
)
|
|
|
|
|
|
|
|
// now unlock and let through the first request
|
|
|
|
unlock()
|
|
|
|
|
|
|
|
await requestApproval
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
res.result && !res.error,
|
|
|
|
'response should have result and no error',
|
|
|
|
)
|
|
|
|
assert.deepEqual(
|
|
|
|
res.result, [ACCOUNTS.c.primary],
|
|
|
|
'response should have correct result',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('wallet_sendDomainMetadata', function () {
|
|
|
|
|
|
|
|
let permController, clock
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
permController = initPermController()
|
|
|
|
clock = sinon.useFakeTimers(1)
|
|
|
|
})
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
clock.restore()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('records domain metadata', async function () {
|
|
|
|
|
|
|
|
const name = 'BAZ'
|
|
|
|
|
|
|
|
const cMiddleware = getPermissionsMiddleware(permController, DOMAINS.c.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin, name)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
cMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(res.result, 'result should be true')
|
|
|
|
|
|
|
|
const metadataStore = permController.store.getState()[METADATA_STORE_KEY]
|
|
|
|
|
|
|
|
assert.deepEqual(
|
|
|
|
metadataStore,
|
|
|
|
{
|
|
|
|
[DOMAINS.c.origin]: {
|
|
|
|
name,
|
|
|
|
host: DOMAINS.c.host,
|
|
|
|
lastUpdated: 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'metadata should have been added to store',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('records domain metadata and preserves extensionId', async function () {
|
|
|
|
|
|
|
|
const extensionId = 'fooExtension'
|
|
|
|
|
|
|
|
const name = 'BAZ'
|
|
|
|
|
|
|
|
const cMiddleware = getPermissionsMiddleware(permController, DOMAINS.c.origin, extensionId)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin, name)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
cMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(res.result, 'result should be true')
|
|
|
|
|
|
|
|
const metadataStore = permController.store.getState()[METADATA_STORE_KEY]
|
|
|
|
|
|
|
|
assert.deepEqual(
|
|
|
|
metadataStore,
|
|
|
|
{ [DOMAINS.c.origin]: { name, extensionId, lastUpdated: 1 } },
|
|
|
|
'metadata should have been added to store',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should not record domain metadata if no name', async function () {
|
|
|
|
|
|
|
|
const name = null
|
|
|
|
|
|
|
|
const cMiddleware = getPermissionsMiddleware(permController, DOMAINS.c.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin, name)
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
cMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(res.result, 'result should be true')
|
|
|
|
|
|
|
|
const metadataStore = permController.store.getState()[METADATA_STORE_KEY]
|
|
|
|
|
|
|
|
assert.deepEqual(
|
|
|
|
metadataStore, {},
|
|
|
|
'metadata should not have been added to store',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should not record domain metadata if no metadata', async function () {
|
|
|
|
|
|
|
|
const cMiddleware = getPermissionsMiddleware(permController, DOMAINS.c.origin)
|
|
|
|
|
|
|
|
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin)
|
|
|
|
delete req.domainMetadata
|
|
|
|
const res = {}
|
|
|
|
|
|
|
|
await assert.doesNotReject(
|
|
|
|
cMiddleware(req, res),
|
|
|
|
'should not reject',
|
|
|
|
)
|
|
|
|
|
|
|
|
assert.ok(res.result, 'result should be true')
|
|
|
|
|
|
|
|
const metadataStore = permController.store.getState()[METADATA_STORE_KEY]
|
|
|
|
|
|
|
|
assert.deepEqual(
|
|
|
|
metadataStore, {},
|
|
|
|
'metadata should not have been added to store',
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|