-
Notifications
You must be signed in to change notification settings - Fork 86
[Bug] Fix False Positive Custom Auth Tests #881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: naga_add_hardcoded_keysets-3
Are you sure you want to change the base?
[Bug] Fix False Positive Custom Auth Tests #881
Conversation
- add missing `maxPrice` in the custom auth payload - e2e: fix custom auths
…alice-auth-manager-data`
@@ -871,6 +872,9 @@ export function createBaseModule<T, M>(config: BaseModuleConfig<T, M>) { | |||
litActionCode: requestBody.litActionCode, | |||
litActionIpfsId: requestBody.litActionIpfsId, | |||
jsParams: requestBody.jsParams, | |||
maxPrice: getUserMaxPrice({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was missing in the payload
@@ -3,7 +3,8 @@ import { assert } from '../assertions'; | |||
|
|||
export const createExecuteJsTest = ( | |||
ctx: Awaited<ReturnType<typeof init>>, | |||
getAuthContext: () => any | |||
getAuthContext: () => any, | |||
pubkey?: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional param for custom auth to pass in pub key instead of using alice's
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not pass the litClient
, chosen authContext
and the publicKey
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the litClient
doesn't have an authContext
. The authContext
is generated separately by an authManager
that could generates:
- eoa auth context
- pkp auth context
- custom pkp auth context
the getAuthContext
function is either one of the above. If custom auth context is passed in by the call site, then we will need the pkp public key.
@@ -3,7 +3,8 @@ import { assert } from '../assertions'; | |||
|
|||
export const createEncryptDecryptFlowTest = ( | |||
ctx: Awaited<ReturnType<typeof init>>, | |||
getAuthContext: () => any | |||
getAuthContext: () => any, | |||
address?: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional param for custom auth to pass in address instead of using alice's
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function params (and similar ones) are quite confusing and easy to break: Caller has to pass a (practially untyped) function to pick an auth context from the same ctx
that it passes, but that auth context is only used to select which of alice's address to use, but on only one case of those, I can override it with address
And to get into that, I had to read the whole function. Without doing that, it is completely impossible to understand what address
does and when to use it for example or what getAuthContext
has to be and do
This would improve if init
returned something like { litClient, alice: { /* alice's stuff */ }, bob: { /* bob's stuff */ }, ... }}
so we could pick bob's context with all its things and alice's address. Her context and the function to get it only increase this function complexity. And this function can properly express what it needs to receive and what its params are for without being restricted to what init
returns
Things inside are also confusing, Why do we even need alice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: (practially untyped)
the type and untype concern will be addressed in a follow up PR after pnpm migration.
re: that auth context is only used to select which of alice's address to use
The address?
field is added purely so custom auth (Eve’s) can override it.
re: ... { litClient, alice: { /* alice's stuff / }, bob: { / bob's stuff */ }
Some tests in this PR were commented out due to messiness caused by these implicit parameters. These were added as a temporary measure to prove that custom auth is working.
A follow-up PR is required to clean this up. [JSS-102]
@@ -3,7 +3,8 @@ import { assert } from '../assertions'; | |||
|
|||
export const createViewPKPsByAddressTest = ( | |||
ctx: Awaited<ReturnType<typeof init>>, | |||
getAuthContext: () => any | |||
getAuthContext: () => any, | |||
pubkey?: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why adding the pubkey
param here? And why we have getAuthContext
if it is not used?
This slightly-different-but-shared interface between some of the functions in this directory is confusing. It is not similar for all files, and doesn't seem to be a reason for that. And is is not even similar on the ones that follow it, some have pubkey
, others address
@@ -3,7 +3,8 @@ import { assert } from '../assertions'; | |||
|
|||
export const createExecuteJsTest = ( | |||
ctx: Awaited<ReturnType<typeof init>>, | |||
getAuthContext: () => any | |||
getAuthContext: () => any, | |||
pubkey?: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not pass the litClient
, chosen authContext
and the publicKey
?
@@ -3,7 +3,8 @@ import { assert } from '../assertions'; | |||
|
|||
export const createEncryptDecryptFlowTest = ( | |||
ctx: Awaited<ReturnType<typeof init>>, | |||
getAuthContext: () => any | |||
getAuthContext: () => any, | |||
address?: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function params (and similar ones) are quite confusing and easy to break: Caller has to pass a (practially untyped) function to pick an auth context from the same ctx
that it passes, but that auth context is only used to select which of alice's address to use, but on only one case of those, I can override it with address
And to get into that, I had to read the whole function. Without doing that, it is completely impossible to understand what address
does and when to use it for example or what getAuthContext
has to be and do
This would improve if init
returned something like { litClient, alice: { /* alice's stuff */ }, bob: { /* bob's stuff */ }, ... }}
so we could pick bob's context with all its things and alice's address. Her context and the function to get it only increase this function complexity. And this function can properly express what it needs to receive and what its params are for without being restricted to what init
returns
Things inside are also confusing, Why do we even need alice?
// CONFIGURATION | ||
const NETWORK = 'naga-dev'; | ||
const SITE_OWNER_ACCOUNT = privateKeyToAccount( | ||
process.env['LIVE_MASTER_ACCOUNT'] as `0x${string}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we unify LIVE_MASTER_ACCOUNT
and LOCAL_MASTER_ACCOUNT
? User should always use an account that corresponds with the target network regardless of it being local or public
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOCAL_MASTER_ACCOUNT
is usually the first anvil account default private key that is automatically funded. If you change that to your own private key, you will still need to local private key to fund your own private key in order to run the local tests. That's why they are separated.
e2e/src/tickets/custom-auth.spec.ts
Outdated
// (async () => { | ||
// const dAppUniqueAuthMethodType = "0x20b2c2163698c4ba8166450ff2378d96c009016deba048b9b125a696c74ea4b5"; | ||
// const { pkpPublicKey, username, password, authMethodId } = jsParams; | ||
|
||
// // Custom validation logic for amazing-app-x35ju8 | ||
// const EXPECTED_USERNAME = 'alice'; | ||
// const EXPECTED_PASSWORD = 'lit'; | ||
// const userIsValid = username === EXPECTED_USERNAME && password === EXPECTED_PASSWORD; | ||
|
||
// // Check PKP permissions | ||
// const tokenId = await Lit.Actions.pubkeyToTokenId({ publicKey: pkpPublicKey }); | ||
// const permittedAuthMethods = await Lit.Actions.getPermittedAuthMethods({ tokenId }); | ||
|
||
// const isPermitted = permittedAuthMethods.some((permittedAuthMethod) => { | ||
// return permittedAuthMethod["auth_method_type"] === dAppUniqueAuthMethodType && | ||
// permittedAuthMethod["id"] === authMethodId; | ||
// }); | ||
|
||
// const isValid = isPermitted && userIsValid; | ||
// LitActions.setResponse({ response: isValid ? "true" : "false" }); | ||
// })(); | ||
// ============================================================ | ||
const validationIpfsCid = 'QmP3ZoTSGQ2P9cAZ4pBUjmPC34xbJZFRoWnCXT2SdHA2uD'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
for (const userId of [ | ||
'alice', | ||
// , 'bob' | ||
]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -898,23 +901,18 @@ export function createBaseModule<T, M>(config: BaseModuleConfig<T, M>) { | |||
handleResponse: async ( | |||
result: z.infer<typeof GenericEncryptedPayloadSchema>, | |||
pkpPublicKey: Hex | string, | |||
jitContext: NagaJitContext | |||
jitContext: NagaJitContext, | |||
requestId?: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only call to this method has requestId
right above and is not passing it here. Let's make it required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the requestId
is added here purely for observation as part of the custom auth test. a separate PR is required to include the request id in all handlers.
WHAT
Custom auth E2E tests were producing false-positive results. It was working because it was using the cached Alice's delegation auth sig instead of using a fresh PKP.
CHANGES
TEST
This PR depends on the hardcoded keysets fixes here
bun test e2e/src/tickets/custom-auth.spec.ts --timeout 500000