Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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];
};

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

/**
Expand Down
27 changes: 13 additions & 14 deletions lib/types/response.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
UserCredentials,
AppCredentials,
AuthArtifacts,
MergeType,
AuthCredentials,
ReqRef,
ReqRefDefaults,
Expand Down Expand Up @@ -386,19 +385,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>>;
credentials: AuthCredentials<AuthUser, AuthApp> & CredentialsExtra;
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 +458,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 +536,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
62 changes: 61 additions & 1 deletion test/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,28 @@ import {
Server,
ServerRoute,
server as createServer,
UserCredentials,
ServerRegisterPluginObject,
Lifecycle,
CachedServerMethod
} from '../..';

const { expect: check } = lab;

type IsAny<T> = (
unknown extends T
? [keyof T] extends [never] ? false : true
: false
);


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

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

server.app.multi = 10;

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

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

const y: IsAny<typeof request.auth.credentials> = false;

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 @@ -63,6 +109,21 @@ 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);

const y: IsAny<typeof request.auth.credentials> = false;
const z: IsAny<typeof request.auth.artifacts> = false;

return 'hello!'
}
};
Expand Down Expand Up @@ -135,7 +196,6 @@ server.method('test.add', (a: number, b: number) => a + b, {
generateKey: (a: number, b: number) => `${a}${b}`
});


server.methods.test.add.cache?.drop(1, 2);

declare module '../..' {
Expand Down