Skip to content

Commit

Permalink
Allow either actor + permission or permissionLevel during Session ins…
Browse files Browse the repository at this point in the history
…tantiation

Fixes #17
  • Loading branch information
aaroncox committed Jan 17, 2023
1 parent c059c4c commit 81f8bbd
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 37 deletions.
15 changes: 13 additions & 2 deletions src/kit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ import {
PermissionLevelType,
} from '@greymass/eosio'

import {Session, SessionOptions, WalletPlugin, WalletPluginLoginOptions} from './session'
import {
Session,
SessionOptions,
WalletPlugin,
WalletPluginContext,
WalletPluginLoginOptions,
} from './session'
import {
AbstractTransactPlugin,
BaseTransactPlugin,
Expand Down Expand Up @@ -178,10 +184,15 @@ export class SessionKit {
walletPlugin: this.walletPlugins[0],
}

const walletContext: WalletPluginContext = {
chain,
permissionLevel: PermissionLevel.from('eosio@active'),
}

const walletOptions: WalletPluginLoginOptions = {
appName: this.appName,
chains: this.chains,
context,
context: walletContext,
}

// Allow overriding of the default wallet plugin by specifying one in the options
Expand Down
26 changes: 21 additions & 5 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
APIClient,
FetchProvider,
Name,
NameType,
PermissionLevel,
PermissionLevelType,
Signature,
Expand Down Expand Up @@ -36,10 +37,15 @@ export interface WalletPluginOptions {
name?: string
}

export interface WalletPluginContext {
chain: ChainDefinition
permissionLevel: PermissionLevelType | string
}

export interface WalletPluginLoginOptions {
appName: Name
chains: ChainDefinition[]
context: SessionOptions
context: WalletPluginContext
}

export interface WalletPluginLoginResponse {
Expand All @@ -61,12 +67,14 @@ export abstract class AbstractWalletPlugin implements WalletPlugin {
* Options for creating a new instance of a [[Session]].
*/
export interface SessionOptions {
actor?: NameType
allowModify?: boolean
broadcast?: boolean
chain: ChainDefinitionType
expireSeconds?: number
fetch?: Fetch
permissionLevel: PermissionLevelType | string
permission?: NameType
permissionLevel?: PermissionLevelType | string
transactPlugins?: AbstractTransactPlugin[]
transactPluginsOptions?: TransactPluginsOptions
walletPlugin: WalletPlugin
Expand Down Expand Up @@ -108,15 +116,23 @@ export class Session {
if (options.transactPluginsOptions) {
this.transactPluginsOptions = options.transactPluginsOptions
}
this.permissionLevel = PermissionLevel.from(options.permissionLevel)
if (options.permissionLevel) {
this.permissionLevel = PermissionLevel.from(options.permissionLevel)
} else if (options.actor && options.permission) {
this.permissionLevel = PermissionLevel.from(`${options.actor}@${options.permission}`)
} else {
throw new Error(
'Either a permissionLevel or actor/permission must be provided when creating a new Session.'
)
}
this.wallet = options.walletPlugin
}

get accountName(): Name {
get actor(): Name {
return this.permissionLevel.actor
}

get permissionName(): Name {
get permission(): Name {
return this.permissionLevel.permission
}

Expand Down
84 changes: 75 additions & 9 deletions test/tests/session.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {assert} from 'chai'

import SessionKit, {BaseTransactPlugin, ChainDefinition, Session, SessionOptions} from '$lib'
import {PermissionLevel, TimePointSec} from '@greymass/eosio'
import {Name, PermissionLevel, TimePointSec} from '@greymass/eosio'

import {mockFetch} from '$test/utils/mock-fetch'
import {MockTransactPlugin, MockTransactResourceProviderPlugin} from '$test/utils/mock-hook'
Expand Down Expand Up @@ -148,6 +148,76 @@ suite('session', function () {
)
})
})
suite('authority', function () {
suite('actor + permission', function () {
test('typed values', async function () {
const testSession = new Session({
actor: Name.from('account'),
chain: ChainDefinition.from({
id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d',
url: 'https://jungle4.greymass.com',
}),
fetch: mockFetch, // Required for unit tests
permission: Name.from('permission'),
walletPlugin: wallet,
})
assert.instanceOf(testSession, Session)
})
test('untyped values', async function () {
const testSession = new Session({
actor: 'account',
chain: ChainDefinition.from({
id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d',
url: 'https://jungle4.greymass.com',
}),
fetch: mockFetch, // Required for unit tests
permission: 'permission',
walletPlugin: wallet,
})
assert.instanceOf(testSession, Session)
})
})
suite('permissionLevel', function () {
test('typed values', async function () {
const testSession = new Session({
chain: ChainDefinition.from({
id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d',
url: 'https://jungle4.greymass.com',
}),
fetch: mockFetch, // Required for unit tests
permissionLevel: PermissionLevel.from('account@permission'),
walletPlugin: wallet,
})
assert.instanceOf(testSession, Session)
})
test('untyped values', async function () {
const testSession = new Session({
actor: 'account',
chain: ChainDefinition.from({
id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d',
url: 'https://jungle4.greymass.com',
}),
fetch: mockFetch, // Required for unit tests
permissionLevel: 'account@permission',
walletPlugin: wallet,
})
assert.instanceOf(testSession, Session)
})
})
test('undefined', function () {
assert.throws(() => {
new Session({
actor: 'account',
chain: ChainDefinition.from({
id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d',
url: 'https://jungle4.greymass.com',
}),
fetch: mockFetch, // Required for unit tests
walletPlugin: wallet,
})
})
})
})
suite('passed as', function () {
test('typed values', async function () {
const testSession = new Session({
Expand Down Expand Up @@ -233,13 +303,9 @@ suite('session', function () {
})
})
test('getters', function () {
assert.equal(
session.accountName,
PermissionLevel.from(mockSessionOptions.permissionLevel).actor
)
assert.equal(
session.permissionName,
PermissionLevel.from(mockSessionOptions.permissionLevel).permission
)
const expectedPermission = PermissionLevel.from(mockPermissionLevel)
// Ensure transaction authority was templated
assert.isTrue(session.actor.equals(expectedPermission.actor))
assert.isTrue(session.permission.equals(expectedPermission.permission))
})
})
35 changes: 14 additions & 21 deletions test/tests/transact.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {assert} from 'chai'
import zlib from 'pako'

import {PermissionLevel, Serializer, Signature, TimePointSec} from '@greymass/eosio'
import {Action, Name, PermissionLevel, Serializer, Signature, TimePointSec} from '@greymass/eosio'
import {ResolvedSigningRequest, SigningRequest} from 'eosio-signing-request'

import SessionKit, {
Expand All @@ -24,6 +24,7 @@ import {
import {makeMockAction, makeMockActions, makeMockTransaction} from '$test/utils/mock-transfer'
import {makeWallet} from '$test/utils/mock-wallet'
import {mockPermissionLevel} from '$test/utils/mock-config'
import {Transfer} from '$test/utils/setup/structs'

const client = makeClient()
const wallet = makeWallet()
Expand Down Expand Up @@ -562,20 +563,14 @@ suite('transact', function () {
})
assert.exists(result.transaction)
if (result.transaction) {
const resolvedPermission = result.transaction.actions[0].authorization[0]
const resolvedData = Transfer.from(result.transaction.actions[0].data)
const expectedPermission = PermissionLevel.from(mockPermissionLevel)
// Ensure transaction authority was templated
assert.equal(
result.transaction.actions[0].authorization[0].actor,
PermissionLevel.from(mockSessionOptions.permissionLevel).actor
)
assert.equal(
result.transaction.actions[0].authorization[0].permission,
PermissionLevel.from(mockSessionOptions.permissionLevel).permission
)
assert.isTrue(resolvedPermission.actor.equals(expectedPermission.actor))
assert.isTrue(resolvedPermission.permission.equals(expectedPermission.permission))
// Ensure transaction data was templated
assert.equal(
result.transaction.actions[0].data.from,
PermissionLevel.from(mockSessionOptions.permissionLevel).actor
)
assert.isTrue(resolvedData.from.equals(expectedPermission.actor))
} else {
assert.fail('Decoded transaction was not returned in result.')
}
Expand All @@ -591,14 +586,12 @@ suite('transact', function () {
assert.exists(result.resolved)
const {resolved} = result
// Ensure it returns resolved request with authority templated
assert.equal(
resolved?.transaction.actions[0].authorization[0].actor,
PermissionLevel.from(mockSessionOptions.permissionLevel).actor
)
assert.equal(
resolved?.transaction.actions[0].authorization[0].permission,
PermissionLevel.from(mockSessionOptions.permissionLevel).permission
)
if (resolved) {
const resolvedPermission = resolved.transaction.actions[0].authorization[0]
const expectedPermission = PermissionLevel.from(mockPermissionLevel)
assert.isTrue(resolvedPermission.actor.equals(expectedPermission.actor))
assert.isTrue(resolvedPermission.permission.equals(expectedPermission.permission))
}
})
test('valid signatures', async function () {
const {action, session} = await mockData()
Expand Down

0 comments on commit 81f8bbd

Please sign in to comment.