Skip to content

Commit a4ab150

Browse files
damusixDanilo AlonsoMarsup
authored
fix: πŸ› accurate auth typings (#4523)
* fix: πŸ› accurate auth typings Previously would resolve to `any`, they now pickup the generic and the ref overrides. * test: πŸ§ͺ test for any * style: πŸ’„ superfluous intersecetion, cleanup respones types --------- Co-authored-by: Danilo Alonso <danilo.alonso@HQ-MC-DALONSO.local> Co-authored-by: Nicolas Morel <nicolas@morel.io>
1 parent 0f1f3bd commit a4ab150

File tree

3 files changed

+95
-24
lines changed

3 files changed

+95
-24
lines changed

β€Žlib/types/request.d.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,24 @@ export interface AppCredentials {
2727
* User-extensible type for request.auth credentials.
2828
*/
2929
export interface AuthCredentials<
30-
AuthUser extends object = UserCredentials,
31-
AuthApp extends object = AppCredentials,
30+
AuthUser = UserCredentials,
31+
AuthApp = AppCredentials
3232
> {
3333
/**
3434
* The application scopes to be granted.
3535
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsauthaccessscope)
3636
*/
3737
scope?: string[] | undefined;
38+
3839
/**
3940
* If set, will only work with routes that set `access.entity` to `user`.
4041
*/
41-
user?: MergeType<UserCredentials, AuthUser> | undefined;
42+
user?: AuthUser
4243

4344
/**
4445
* If set, will only work with routes that set `access.entity` to `app`.
4546
*/
46-
app?: MergeType<AppCredentials, AuthApp> | undefined;
47+
app?: AuthApp;
4748
}
4849

4950
export interface AuthArtifacts {
@@ -65,15 +66,20 @@ export type AuthMode = 'required' | 'optional' | 'try';
6566
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-requestauth)
6667
*/
6768
export interface RequestAuth<
68-
AuthUser extends object = UserCredentials,
69-
AuthApp extends object = AppCredentials,
70-
CredentialsExtra extends object = Record<string, unknown>,
69+
AuthUser = UserCredentials,
70+
AuthApp = AppCredentials,
71+
CredentialsExtra = Record<string, unknown>,
7172
ArtifactsExtra = Record<string, unknown>
7273
> {
7374
/** an artifact object received from the authentication strategy and used in authentication-related actions. */
7475
artifacts: ArtifactsExtra;
7576
/** the credential object received during the authentication process. The presence of an object does not mean successful authentication. */
76-
credentials: MergeType<CredentialsExtra, AuthCredentials<AuthUser, AuthApp>>;
77+
credentials: (
78+
79+
AuthCredentials<AuthUser, AuthApp> &
80+
CredentialsExtra
81+
);
82+
7783
/** the authentication error is failed and mode set to 'try'. */
7884
error: Error;
7985
/** true if the request has been successfully authenticated, otherwise false. */
@@ -89,6 +95,7 @@ export interface RequestAuth<
8995
strategy: string;
9096
}
9197

98+
9299
/**
93100
* 'peek' - emitted for each chunk of payload data read from the client connection. The event method signature is function(chunk, encoding).
94101
* 'finish' - emitted when the request payload finished reading. The event method signature is function ().
@@ -296,7 +303,12 @@ export type ReqRef = Partial<Record<keyof ReqRefDefaults, unknown>>;
296303
/**
297304
* Utilities for merging request refs and other things
298305
*/
299-
export type MergeType<T extends object, U extends object> = Omit<T, keyof U> & U;
306+
export type MergeType<T, U> = {
307+
[K in keyof T]: K extends keyof U
308+
? U[K]
309+
: T[K];
310+
};
311+
300312
export type MergeRefs<T extends ReqRef> = MergeType<ReqRefDefaults, T>;
301313

302314
/**

β€Žlib/types/response.d.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
UserCredentials,
77
AppCredentials,
88
AuthArtifacts,
9-
MergeType,
109
AuthCredentials,
1110
ReqRef,
1211
ReqRefDefaults,
@@ -386,19 +385,19 @@ export type ResponseValue = string | object;
386385

387386
export interface AuthenticationData<
388387

389-
AuthUser extends object = UserCredentials,
390-
AuthApp extends object = AppCredentials,
391-
CredentialsExtra extends object = Record<string, unknown>,
388+
AuthUser = UserCredentials,
389+
AuthApp = AppCredentials,
390+
CredentialsExtra = Record<string, unknown>,
392391
ArtifactsExtra = AuthArtifacts
393392
> {
394-
credentials: MergeType<CredentialsExtra, AuthCredentials<AuthUser, AuthApp>>;
393+
credentials: AuthCredentials<AuthUser, AuthApp> & CredentialsExtra;
395394
artifacts?: ArtifactsExtra | undefined;
396395
}
397396

398397
export interface Auth<
399-
AuthUser extends object = UserCredentials,
400-
AuthApp extends object = AppCredentials,
401-
CredentialsExtra extends object = Record<string, unknown>,
398+
AuthUser = UserCredentials,
399+
AuthApp = AppCredentials,
400+
CredentialsExtra = Record<string, unknown>,
402401
ArtifactsExtra = AuthArtifacts
403402
> {
404403
readonly isAuth: true;
@@ -459,9 +458,9 @@ export interface ResponseToolkit<Refs extends ReqRef = ReqRefDefaults> {
459458
* @return Return value: an internal authentication object.
460459
*/
461460
authenticated <
462-
AuthUser extends object = MergeRefs<Refs>['AuthUser'],
463-
AuthApp extends object = MergeRefs<Refs>['AuthApp'],
464-
CredentialsExtra extends object = MergeRefs<Refs>['AuthCredentialsExtra'],
461+
AuthUser = MergeRefs<Refs>['AuthUser'],
462+
AuthApp = MergeRefs<Refs>['AuthApp'],
463+
CredentialsExtra = MergeRefs<Refs>['AuthCredentialsExtra'],
465464
ArtifactsExtra = MergeRefs<Refs>['AuthArtifactsExtra']
466465
>(
467466
data: (
@@ -537,9 +536,9 @@ export interface ResponseToolkit<Refs extends ReqRef = ReqRefDefaults> {
537536
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-hunauthenticatederror-data)
538537
*/
539538
unauthenticated <
540-
AuthUser extends object = MergeRefs<Refs>['AuthUser'],
541-
AuthApp extends object = MergeRefs<Refs>['AuthApp'],
542-
CredentialsExtra extends object = MergeRefs<Refs>['AuthCredentialsExtra'],
539+
AuthUser = MergeRefs<Refs>['AuthUser'],
540+
AuthApp = MergeRefs<Refs>['AuthApp'],
541+
CredentialsExtra = MergeRefs<Refs>['AuthCredentialsExtra'],
543542
ArtifactsExtra = MergeRefs<Refs>['AuthArtifactsExtra']
544543
>(
545544
error: Error,

β€Žtest/types/index.ts

+61-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,28 @@ import {
1010
Server,
1111
ServerRoute,
1212
server as createServer,
13+
UserCredentials,
1314
ServerRegisterPluginObject,
1415
Lifecycle,
1516
CachedServerMethod
1617
} from '../..';
1718

1819
const { expect: check } = lab;
1920

21+
type IsAny<T> = (
22+
unknown extends T
23+
? [keyof T] extends [never] ? false : true
24+
: false
25+
);
26+
27+
28+
declare module '../..' {
29+
interface UserCredentials {
30+
someId: string;
31+
someName: string;
32+
}
33+
}
34+
2035
interface ServerAppSpace {
2136
multi?: number;
2237
}
@@ -29,13 +44,44 @@ check.type<MyServer>(server);
2944

3045
server.app.multi = 10;
3146

47+
const genericRoute: ServerRoute = {
48+
method: 'GET',
49+
path: '/',
50+
handler: (request, h) => {
51+
52+
check.type<UserCredentials>(request.auth.credentials!.user!);
53+
54+
const y: IsAny<typeof request.auth.credentials> = false;
55+
56+
return 'hello!';
57+
}
58+
}
59+
60+
server.route(genericRoute);
61+
3262
interface RequestDecorations {
3363
Server: MyServer;
3464
RequestApp: {
3565
word: string;
3666
},
3767
RouteApp: {
3868
prefix: string[];
69+
},
70+
AuthUser: {
71+
id: string,
72+
name: string
73+
email: string
74+
},
75+
AuthCredentialsExtra: {
76+
test: number
77+
}
78+
AuthApp: {
79+
key: string
80+
name: string
81+
},
82+
AuthArtifactsExtra: {
83+
some: string
84+
thing: number
3985
}
4086
}
4187

@@ -63,6 +109,21 @@ const route: ServerRoute<RequestDecorations> = {
63109
check.type<number>(request.server.app.multi!);
64110
check.type<string[]>(request.route.settings.app!.prefix);
65111

112+
check.type<number>(request.auth.credentials!.test);
113+
114+
check.type<string>(request.auth.credentials!.user!.email);
115+
check.type<string>(request.auth.credentials!.user!.id);
116+
check.type<string>(request.auth.credentials!.user!.name);
117+
118+
check.type<string>(request.auth.credentials!.app!.name);
119+
check.type<string>(request.auth.credentials!.app!.key);
120+
121+
check.type<string>(request.auth.artifacts.some);
122+
check.type<number>(request.auth.artifacts.thing);
123+
124+
const y: IsAny<typeof request.auth.credentials> = false;
125+
const z: IsAny<typeof request.auth.artifacts> = false;
126+
66127
return 'hello!'
67128
}
68129
};
@@ -135,7 +196,6 @@ server.method('test.add', (a: number, b: number) => a + b, {
135196
generateKey: (a: number, b: number) => `${a}${b}`
136197
});
137198

138-
139199
server.methods.test.add.cache?.drop(1, 2);
140200

141201
declare module '../..' {

0 commit comments

Comments
Β (0)