-
Notifications
You must be signed in to change notification settings - Fork 90
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
feat(auth): add typings to request contexts & bodies #821
Conversation
packages/auth/src/app.ts
Outdated
} | ||
|
||
type InteractionContext< | ||
BodyT = never, |
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.
It looks like there's never a specified body type, and I don't know if it needs to be enforced as never
BodyT = never, |
packages/auth/src/grant/routes.ts
Outdated
interface StartQuery { | ||
clientName: string | ||
clientUri: 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.
clientName
and clientUri
should be added to the OpenAPI spec to be enforced:
parameters: |
packages/auth/src/grant/routes.ts
Outdated
interface FinishParams { | ||
id: string | ||
nonce: 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.
Maybe StartParams
and FinishParams
could be consolidated into a single interface
packages/auth/src/app.ts
Outdated
QueryT = ParsedUrlQuery, | ||
ParamsT = { [key: string]: 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.
It looks like these are always defined and don't need defaults
QueryT = ParsedUrlQuery, | |
ParamsT = { [key: string]: string } | |
QueryT, | |
ParamsT } |
packages/auth/src/app.ts
Outdated
request: ManagementRequest<ParamsT> | ||
} | ||
|
||
export type CreateContext<BodyT> = GrantContext<BodyT> |
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.
Is this needed? Can GrantContext
just be used?
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.
GrantContext
can definitely just be used, but I was following the pattern here:
rafiki/packages/backend/src/app.ts
Line 107 in a0302b3
export type CreateContext<BodyT> = CollectionContext<BodyT> |
packages/auth/src/app.ts
Outdated
type ManagementRequest<ParamsT = { [key: string]: string }> = Omit< | ||
AppContext['request'], | ||
'body' | ||
> & { | ||
params?: ParamsT | ||
} | ||
|
||
type ManagementContext<ParamsT = { [key: string]: string }> = Omit< | ||
AppContext, | ||
'request' | ||
> & { | ||
request: ManagementRequest<ParamsT> | ||
} |
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.
type ManagementRequest<ParamsT = { [key: string]: string }> = Omit< | |
AppContext['request'], | |
'body' | |
> & { | |
params?: ParamsT | |
} | |
type ManagementContext<ParamsT = { [key: string]: string }> = Omit< | |
AppContext, | |
'request' | |
> & { | |
request: ManagementRequest<ParamsT> | |
} | |
type ManagementRequest<ParamsT = { [key: string]: string }> = Omit< | |
AppContext['request'], | |
'params' | |
> & { | |
params: Record<'id', string> | |
} | |
export type ManagementContext = Omit< | |
AppContext, | |
'request' | |
> & { | |
request: ManagementRequest | |
} |
I think 👆 can replace RevokeContext
, RotateContext
, and ManageParams
0ecd9a2
to
c3e834e
Compare
packages/auth/src/app.ts
Outdated
export type IntrospectContext<BodyT> = TokenContext<BodyT> | ||
export type RevokeContext = ManagementContext | ||
export type RotateContext = ManagementContext | ||
|
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 calls to createValidatorMiddleware
below should specify the type guarded context.
For example:
rafiki/packages/auth/src/app.ts
Lines 196 to 206 in e067823
this.publicRouter.post( | |
'/', | |
createValidatorMiddleware(openApi.authServerSpec, { | |
path: '/', | |
method: HttpMethod.POST | |
}), | |
this.config.bypassSignatureValidation | |
? (ctx, next) => next() | |
: grantInitiationHttpsigMiddleware, | |
grantRoutes.create | |
) |
should change to have
createValidatorMiddleware<CreateContext>(openApi.authServerSpec, {
path: '/',
method: HttpMethod.POST
})
That gets tricky without having the particular BodyT
defined in this file.
One solution is to use:
rafiki/packages/backend/src/app.ts
Lines 112 to 117 in e067823
type ContextType<T> = T extends ( | |
ctx: infer Context | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
) => any | |
? Context | |
: never |
then have
createValidatorMiddleware<Context<grantRoutes.create>>(openApi.authServerSpec, {
path: '/',
method: HttpMethod.POST
})
in which case a lot of these contexts can be defined in their corresponding routes.ts
file and be defined with the specific generic type (BodyT
, etc)
packages/auth/src/app.ts
Outdated
path: '/', | ||
method: HttpMethod.POST | ||
}), | ||
createValidatorMiddleware<ContextType<typeof grantCreate>>( |
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.
Could we just import CreateContext
and ditch ContextType
+ the typed grantCreate
definition?
createValidatorMiddleware<ContextType<typeof grantCreate>>( | |
createValidatorMiddleware<CreateContext>( |
ditto elsewhere
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.
It seems like the type of ContextType
and the like don't seem to be compatible unless it's cast to AppContext
like in the current implementation.
Type 'CreateContext' does not satisfy the constraint 'ExtendableContext & { state: DefaultState; } & DefaultContext & { body: unknown; response: { body: unknown; }; }'.
Type 'CreateContext' is missing the following properties from type 'ExtendableContext': app, response, req, res, and 52 more.
(alias) type CreateContext = Omit<AppContext, "request"> & {
request: GrantRequest<GrantRequestBody, ParsedUrlQuery>;
clientKeyId: 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.
🤔
Maybe this extends Koa.ParameterizedContext
is causing us more trouble than it's worth?
export function createValidatorMiddleware<T extends Koa.ParameterizedContext>( |
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.
either that or we should be less cavalier with Omit
ing parts of AppContext
rafiki/packages/backend/src/app.ts
Lines 70 to 73 in 8054dc5
export type AppRequest<ParamsT extends string = string> = Omit< | |
AppContext['request'], | |
'params' | |
> & { |
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.
🤔 Maybe this
extends Koa.ParameterizedContext
is causing us more trouble than it's worth?
export function createValidatorMiddleware<T extends Koa.ParameterizedContext>(
It's caused me issues in the past when trying to add session middleware to the AS:
rafiki/packages/auth/src/app.ts
Lines 117 to 119 in 8054dc5
// Only accepts Middleware<DefaultState, DefaultContext> for some reason, this.koa is Middleware<DefaultState, AppContext> | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
this.koa as any |
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 vote we remove the extends Koa.ParameterizedContext
in openapi
's createValidatorMiddleware
(assuming that makes using our desired contexts possible)
(I'm not sure if that will help with your previous session type issue though.)
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.
It seems like the general issue is that Koa.ParameterizedContext
doesn't seem to produce a type that's assignable to the base Koa context, or that at least the session middleware doesn't expect it as a possible type for a koa context.
All for removing extends Koa.ParameterizedContext
if it works, though. It'll at least lift that restriction for the validator middleware.
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.
Meanwhile, renovates over here saying: "Help me help you!"
(I don't know if it'll help)
ceceb1d
to
b85f3d9
Compare
b85f3d9
to
20ff4fd
Compare
packages/auth/src/app.ts
Outdated
const { | ||
create: grantCreate, | ||
continue: grantContinue | ||
}: { | ||
create: (ctx: AppContext) => Promise<void> | ||
continue: (ctx: AppContext) => Promise<void> | ||
} = grantRoutes |
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 these can be removed
const { | |
create: grantCreate, | |
continue: grantContinue | |
}: { | |
create: (ctx: AppContext) => Promise<void> | |
continue: (ctx: AppContext) => Promise<void> | |
} = grantRoutes |
Changes proposed in this pull request
Context
Closes #351, or more precisely, closes the reason it was reopened.
Checklist
fixes #number