-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathauth-github.strategy.ts
More file actions
97 lines (85 loc) · 3.03 KB
/
Copy pathauth-github.strategy.ts
File metadata and controls
97 lines (85 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { Strategy } from 'passport-github';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import {
FederatedOAuthService,
FederatedCredentialsInterface,
} from '@concepta/nestjs-federated';
import {
AUTH_GITHUB_AUTHENTICATION_TYPE,
AUTH_GITHUB_MODULE_SETTINGS_TOKEN,
AUTH_GITHUB_STRATEGY_NAME,
} from './auth-github.constants';
import { AuthGithubSettingsInterface } from './interfaces/auth-github-settings.interface';
import { AuthGithubProfileInterface } from './interfaces/auth-github-profile.interface';
import { AuthGithubMissingEmailException } from './exceptions/auth-github-missing-email.exception';
import { AuthGithubMissingIdException } from './exceptions/auth-github-missing-id.exception';
import { mapProfile } from './utils/auth-github-map-profile';
import { AuthGithubAuthenticatedEventAsync } from './events/auth-github-authenticated.event';
import { getAuthenticatedUserInfo } from '@concepta/nestjs-authentication/src';
import { AuthenticationRequestInterface } from '@concepta/nestjs-authentication';
@Injectable()
export class AuthGithubStrategy extends PassportStrategy(
Strategy,
AUTH_GITHUB_STRATEGY_NAME,
) {
constructor(
@Inject(AUTH_GITHUB_MODULE_SETTINGS_TOKEN)
private settings: AuthGithubSettingsInterface,
private federatedOAuthService: FederatedOAuthService,
) {
super({
clientID: settings?.clientId,
clientSecret: settings?.clientSecret,
callbackURL: settings?.callbackURL,
passReqToCallback: true,
});
}
async validate(
req: AuthenticationRequestInterface,
_accessToken: string,
_refreshToken: string,
profile: AuthGithubProfileInterface,
): Promise<FederatedCredentialsInterface> {
const gitProfile = this.settings.mapProfile
? this.settings.mapProfile(profile)
: mapProfile(profile);
if (!gitProfile?.id) {
throw new AuthGithubMissingIdException();
}
if (!gitProfile?.email) {
throw new AuthGithubMissingEmailException();
}
// Create a new user if it doesn't exist or just return based on federated
const user = await this.federatedOAuthService.sign(
AUTH_GITHUB_STRATEGY_NAME,
gitProfile.email,
gitProfile.id,
);
if (!user) {
throw new UnauthorizedException();
}
await this.dispatchAuthAttemptEvent(req, user.id, true);
return user;
}
protected async dispatchAuthAttemptEvent(
req: AuthenticationRequestInterface,
userId: string,
success: boolean,
failureReason?: string | null,
): Promise<void> {
const info = getAuthenticatedUserInfo(req);
const failMessage = failureReason ? { failureReason } : {};
const authenticatedEventAsync = new AuthGithubAuthenticatedEventAsync({
userInfo: {
userId: userId,
ipAddress: info.ipAddress || '',
deviceInfo: info.deviceInfo || '',
authType: AUTH_GITHUB_AUTHENTICATION_TYPE,
success,
...failMessage,
},
});
await authenticatedEventAsync.emit();
}
}