Skip to content

Commit

Permalink
fix: 🐛 accurate auth typings
Browse files Browse the repository at this point in the history
Previously would resolve to `any`, they now pickup the generic and the
ref overrides.
  • Loading branch information
Danilo Alonso authored and Danilo Alonso committed Aug 9, 2024
1 parent 22377ee commit d2d29ad
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 22 deletions.
30 changes: 21 additions & 9 deletions lib/types/request.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,24 @@ export interface AppCredentials {
* User-extensible type for request.auth credentials.
*/
export interface AuthCredentials<
AuthUser extends object = UserCredentials,
AuthApp extends object = AppCredentials,
AuthUser = UserCredentials,
AuthApp = AppCredentials
> {
/**
* The application scopes to be granted.
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsauthaccessscope)
*/
scope?: string[] | undefined;

/**
* If set, will only work with routes that set `access.entity` to `user`.
*/
user?: MergeType<UserCredentials, AuthUser> | undefined;
user?: AuthUser

/**
* If set, will only work with routes that set `access.entity` to `app`.
*/
app?: MergeType<AppCredentials, AuthApp> | undefined;
app?: AuthApp;
}

export interface AuthArtifacts {
Expand All @@ -65,15 +66,20 @@ export type AuthMode = 'required' | 'optional' | 'try';
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-requestauth)
*/
export interface RequestAuth<
AuthUser extends object = UserCredentials,
AuthApp extends object = AppCredentials,
CredentialsExtra extends object = Record<string, unknown>,
AuthUser = UserCredentials,
AuthApp = AppCredentials,
CredentialsExtra = Record<string, unknown>,
ArtifactsExtra = Record<string, unknown>
> {
/** an artifact object received from the authentication strategy and used in authentication-related actions. */
artifacts: ArtifactsExtra;
/** the credential object received during the authentication process. The presence of an object does not mean successful authentication. */
credentials: MergeType<CredentialsExtra, AuthCredentials<AuthUser, AuthApp>>;
credentials: (

AuthCredentials<AuthUser, AuthApp> &
CredentialsExtra
);

/** the authentication error is failed and mode set to 'try'. */
error: Error;
/** true if the request has been successfully authenticated, otherwise false. */
Expand All @@ -89,6 +95,7 @@ export interface RequestAuth<
strategy: string;
}


/**
* 'peek' - emitted for each chunk of payload data read from the client connection. The event method signature is function(chunk, encoding).
* 'finish' - emitted when the request payload finished reading. The event method signature is function ().
Expand Down Expand Up @@ -296,7 +303,12 @@ export type ReqRef = Partial<Record<keyof ReqRefDefaults, unknown>>;
/**
* Utilities for merging request refs and other things
*/
export type MergeType<T extends object, U extends object> = Omit<T, keyof U> & U;
export type MergeType<T, U> = {
[K in keyof T]: K extends keyof U
? U[K]
: T[K];
} & U;

export type MergeRefs<T extends ReqRef> = MergeType<ReqRefDefaults, T>;

/**
Expand Down
24 changes: 12 additions & 12 deletions lib/types/response.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,19 +386,19 @@ export type ResponseValue = string | object;

export interface AuthenticationData<

AuthUser extends object = UserCredentials,
AuthApp extends object = AppCredentials,
CredentialsExtra extends object = Record<string, unknown>,
AuthUser = UserCredentials,
AuthApp = AppCredentials,
CredentialsExtra = Record<string, unknown>,
ArtifactsExtra = AuthArtifacts
> {
credentials: MergeType<CredentialsExtra, AuthCredentials<AuthUser, AuthApp>>;
artifacts?: ArtifactsExtra | undefined;
}

export interface Auth<
AuthUser extends object = UserCredentials,
AuthApp extends object = AppCredentials,
CredentialsExtra extends object = Record<string, unknown>,
AuthUser = UserCredentials,
AuthApp = AppCredentials,
CredentialsExtra = Record<string, unknown>,
ArtifactsExtra = AuthArtifacts
> {
readonly isAuth: true;
Expand Down Expand Up @@ -459,9 +459,9 @@ export interface ResponseToolkit<Refs extends ReqRef = ReqRefDefaults> {
* @return Return value: an internal authentication object.
*/
authenticated <
AuthUser extends object = MergeRefs<Refs>['AuthUser'],
AuthApp extends object = MergeRefs<Refs>['AuthApp'],
CredentialsExtra extends object = MergeRefs<Refs>['AuthCredentialsExtra'],
AuthUser = MergeRefs<Refs>['AuthUser'],
AuthApp = MergeRefs<Refs>['AuthApp'],
CredentialsExtra = MergeRefs<Refs>['AuthCredentialsExtra'],
ArtifactsExtra = MergeRefs<Refs>['AuthArtifactsExtra']
>(
data: (
Expand Down Expand Up @@ -537,9 +537,9 @@ export interface ResponseToolkit<Refs extends ReqRef = ReqRefDefaults> {
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-hunauthenticatederror-data)
*/
unauthenticated <
AuthUser extends object = MergeRefs<Refs>['AuthUser'],
AuthApp extends object = MergeRefs<Refs>['AuthApp'],
CredentialsExtra extends object = MergeRefs<Refs>['AuthCredentialsExtra'],
AuthUser = MergeRefs<Refs>['AuthUser'],
AuthApp = MergeRefs<Refs>['AuthApp'],
CredentialsExtra = MergeRefs<Refs>['AuthCredentialsExtra'],
ArtifactsExtra = MergeRefs<Refs>['AuthArtifactsExtra']
>(
error: Error,
Expand Down
50 changes: 49 additions & 1 deletion test/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ import {
Server,
ServerRoute,
server as createServer,
ServerRegisterPluginObject
UserCredentials
} from '../..';

const { expect: check } = lab;

declare module '../..' {
interface UserCredentials {
someId: string;
someName: string;
}
}

interface ServerAppSpace {
multi?: number;
}
Expand All @@ -27,13 +34,42 @@ check.type<MyServer>(server);

server.app.multi = 10;

const genericRoute: ServerRoute = {
method: 'GET',
path: '/',
handler: (request, h) => {

check.type<UserCredentials>(request.auth.credentials!.user!);

return 'hello!';
}
}

server.route(genericRoute);

interface RequestDecorations {
Server: MyServer;
RequestApp: {
word: string;
},
RouteApp: {
prefix: string[];
},
AuthUser: {
id: string,
name: string
email: string
},
AuthCredentialsExtra: {
test: number
}
AuthApp: {
key: string
name: string
},
AuthArtifactsExtra: {
some: string
thing: number
}
}

Expand Down Expand Up @@ -61,6 +97,18 @@ const route: ServerRoute<RequestDecorations> = {
check.type<number>(request.server.app.multi!);
check.type<string[]>(request.route.settings.app!.prefix);

check.type<number>(request.auth.credentials!.test);

check.type<string>(request.auth.credentials!.user!.email);
check.type<string>(request.auth.credentials!.user!.id);
check.type<string>(request.auth.credentials!.user!.name);

check.type<string>(request.auth.credentials!.app!.name);
check.type<string>(request.auth.credentials!.app!.key);

check.type<string>(request.auth.artifacts.some);
check.type<number>(request.auth.artifacts.thing);

return 'hello!'
}
};
Expand Down

0 comments on commit d2d29ad

Please sign in to comment.