Skip to content
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

WIP: Feature/login locked #342

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions packages/nestjs-auth-apple/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@concepta/nestjs-authentication": "^6.0.0-alpha.1",
"@concepta/nestjs-common": "^6.0.0-alpha.1",
"@concepta/nestjs-event": "^6.0.0-alpha.1",
"@concepta/nestjs-exception": "^6.0.0-alpha.1",
"@concepta/nestjs-federated": "^6.0.0-alpha.1",
"@concepta/nestjs-jwt": "^6.0.0-alpha.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/nestjs-auth-apple/src/auth-apple.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ export const AUTH_APPLE_VERIFY_ALGORITHM = 'RS256';
export const AUTH_APPLE_TOKEN_ISSUER = 'https://appleid.apple.com';

export const AUTH_APPLE_JWT_KEYS = 'https://appleid.apple.com/auth/keys';

export const AUTH_APPLE_AUTHENTICATION_TYPE = 'auth-apple';
2 changes: 2 additions & 0 deletions packages/nestjs-auth-apple/src/auth-apple.module.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { AuthAppleModule } from './auth-apple.module';

import { FederatedEntityFixture } from './__fixtures__/federated-entity.fixture';
import { UserEntityFixture } from './__fixtures__/user.entity.fixture';
import { EventModule } from '@concepta/nestjs-event';

describe(AuthAppleModule, () => {
let authAppleModule: AuthAppleModule;
Expand All @@ -31,6 +32,7 @@ describe(AuthAppleModule, () => {
entities: [UserEntityFixture, FederatedEntityFixture],
}),
JwtModule.forRoot({}),
EventModule.forRoot({}),
AuthAppleModule.forRoot({}),
AuthenticationModule.forRoot({}),
AuthJwtModule.forRootAsync({
Expand Down
33 changes: 32 additions & 1 deletion packages/nestjs-auth-apple/src/auth-apple.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@concepta/nestjs-federated';

import {
AUTH_APPLE_AUTHENTICATION_TYPE,
AUTH_APPLE_MODULE_SETTINGS_TOKEN,
AUTH_APPLE_SERVICE_TOKEN,
AUTH_APPLE_STRATEGY_NAME,
Expand All @@ -19,6 +20,11 @@ import { Strategy } from 'passport-apple';
import { AuthAppleServiceInterface } from './interfaces/auth-apple-service.interface';
import { mapProfile } from './utils/auth-apple-map-profile';
import { AuthAppleCredentialsInterface } from './interfaces/auth-apple-credentials.interface';
import { AuthAppleAuthenticatedEventAsync } from './events/auth-apple-authenticated.event';
import {
AuthenticationRequestInterface,
getAuthenticatedUserInfo,
} from '@concepta/nestjs-authentication';

@Injectable()
export class AuthAppleStrategy extends PassportStrategy(
Expand All @@ -41,10 +47,11 @@ export class AuthAppleStrategy extends PassportStrategy(
privateKeyString: settings?.privateKeyString,
callbackURL: settings?.callbackURL,
scope: settings?.scope,
passReqToCallback: false,
passReqToCallback: true,
});
}
async validate(
req: AuthenticationRequestInterface,
_accessToken: string,
_refreshToken: string,
idToken: string,
Expand Down Expand Up @@ -73,6 +80,7 @@ export class AuthAppleStrategy extends PassportStrategy(
throw new UnauthorizedException();
}

await this.dispatchAuthAttemptEvent(req, user.id, true);
return user;
}

Expand All @@ -87,4 +95,27 @@ export class AuthAppleStrategy extends PassportStrategy(
throw new AuthAppleMissingEmailException();
}
}

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 AuthAppleAuthenticatedEventAsync({
userInfo: {
userId: userId,
ipAddress: info.ipAddress || '',
deviceInfo: info.deviceInfo || '',
authType: AUTH_APPLE_AUTHENTICATION_TYPE,
success,
...failMessage,
},
});

await authenticatedEventAsync.emit();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AuthenticatedEventInterface } from '@concepta/nestjs-common';
import { EventAsync } from '@concepta/nestjs-event';

export class AuthAppleAuthenticatedEventAsync extends EventAsync<
AuthenticatedEventInterface,
boolean
> {}
1 change: 1 addition & 0 deletions packages/nestjs-auth-github/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@concepta/nestjs-authentication": "^6.0.0-alpha.1",
"@concepta/nestjs-common": "^6.0.0-alpha.1",
"@concepta/nestjs-event": "^6.0.0-alpha.1",
"@concepta/nestjs-exception": "^6.0.0-alpha.1",
"@concepta/nestjs-federated": "^6.0.0-alpha.1",
"@nestjs/common": "^10.4.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/nestjs-auth-github/src/auth-github.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export const AUTH_GITHUB_MODULE_DEFAULT_SETTINGS_TOKEN =
'AUTH_GITHUB_MODULE_DEFAULT_SETTINGS_TOKEN';

export const AUTH_GITHUB_STRATEGY_NAME = 'github';

export const AUTH_GITHUB_AUTHENTICATION_TYPE = 'auth-github';
16 changes: 8 additions & 8 deletions packages/nestjs-auth-github/src/auth-github.controller.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Controller, Inject, Get, UseGuards } from '@nestjs/common';
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
import {
AuthenticatedUserInterface,
AuthenticationResponseInterface,
} from '@concepta/nestjs-common';
import {
AuthUser,
IssueTokenServiceInterface,
AuthenticationJwtResponseDto,
AuthPublic,
AuthUser,
IssueTokenServiceInterface,
} from '@concepta/nestjs-authentication';
import {
AuthenticatedUserInterface,
AuthenticationResponseInterface,
} from '@concepta/nestjs-common';
import { Controller, Get, Inject, UseGuards } from '@nestjs/common';
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { AUTH_GITHUB_ISSUE_TOKEN_SERVICE_TOKEN } from './auth-github.constants';
import { AuthGithubGuard } from './auth-github.guard';

Expand Down
31 changes: 30 additions & 1 deletion packages/nestjs-auth-github/src/auth-github.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@concepta/nestjs-federated';

import {
AUTH_GITHUB_AUTHENTICATION_TYPE,
AUTH_GITHUB_MODULE_SETTINGS_TOKEN,
AUTH_GITHUB_STRATEGY_NAME,
} from './auth-github.constants';
Expand All @@ -17,6 +18,9 @@ import { AuthGithubProfileInterface } from './interfaces/auth-github-profile.int
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(
Expand All @@ -32,10 +36,12 @@ export class AuthGithubStrategy extends PassportStrategy(
clientID: settings?.clientId,
clientSecret: settings?.clientSecret,
callbackURL: settings?.callbackURL,
passReqToCallback: true,
});
}

async validate(
req: AuthenticationRequestInterface,
_accessToken: string,
_refreshToken: string,
profile: AuthGithubProfileInterface,
Expand All @@ -62,7 +68,30 @@ export class AuthGithubStrategy extends PassportStrategy(
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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AuthenticatedEventInterface } from '@concepta/nestjs-common';
import { EventAsync } from '@concepta/nestjs-event';

export class AuthGithubAuthenticatedEventAsync extends EventAsync<
AuthenticatedEventInterface,
boolean
> {}
1 change: 1 addition & 0 deletions packages/nestjs-auth-google/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@concepta/nestjs-authentication": "^6.0.0-alpha.1",
"@concepta/nestjs-common": "^6.0.0-alpha.1",
"@concepta/nestjs-event": "^6.0.0-alpha.1",
"@concepta/nestjs-exception": "^6.0.0-alpha.1",
"@concepta/nestjs-federated": "^6.0.0-alpha.1",
"@nestjs/common": "^10.4.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/nestjs-auth-google/src/auth-google.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export const AUTH_GOOGLE_MODULE_DEFAULT_SETTINGS_TOKEN =
'AUTH_GOOGLE_MODULE_DEFAULT_SETTINGS_TOKEN';

export const AUTH_GOOGLE_STRATEGY_NAME = 'google';

export const AUTH_GOOGLE_AUTHENTICATION_TYPE = 'auth-google';
32 changes: 32 additions & 0 deletions packages/nestjs-auth-google/src/auth-google.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@concepta/nestjs-federated';

import {
AUTH_GOOGLE_AUTHENTICATION_TYPE,
AUTH_GOOGLE_MODULE_SETTINGS_TOKEN,
AUTH_GOOGLE_STRATEGY_NAME,
} from './auth-google.constants';
Expand All @@ -17,6 +18,11 @@ import { AuthGoogleMissingEmailException } from './exceptions/auth-google-missin
import { AuthGoogleMissingIdException } from './exceptions/auth-google-missing-id.exception';
import { mapProfile } from './utils/auth-google-map-profile';
import { Strategy } from 'passport-google-oauth20';
import {
AuthenticationRequestInterface,
getAuthenticatedUserInfo,
} from '@concepta/nestjs-authentication';
import { AuthGoogleAuthenticatedEventAsync } from './events/auth-google-authenticated.event';

@Injectable()
export class AuthGoogleStrategy extends PassportStrategy(
Expand All @@ -33,10 +39,12 @@ export class AuthGoogleStrategy extends PassportStrategy(
clientSecret: settings?.clientSecret,
callbackURL: settings?.callbackURL,
scope: settings?.scope,
passReqToCallback: true,
});
}

async validate(
req: AuthenticationRequestInterface,
_accessToken: string,
_refreshToken: string,
profile: AuthGoogleProfileInterface,
Expand Down Expand Up @@ -64,6 +72,30 @@ export class AuthGoogleStrategy extends PassportStrategy(
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 AuthGoogleAuthenticatedEventAsync({
userInfo: {
userId: userId,
ipAddress: info.ipAddress || '',
deviceInfo: info.deviceInfo || '',
authType: AUTH_GOOGLE_AUTHENTICATION_TYPE,
success,
...failMessage,
},
});

await authenticatedEventAsync.emit();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AuthenticatedEventInterface } from '@concepta/nestjs-common';
import { EventAsync } from '@concepta/nestjs-event';

export class AuthGoogleAuthenticatedEventAsync extends EventAsync<
AuthenticatedEventInterface,
boolean
> {}
18 changes: 18 additions & 0 deletions packages/nestjs-auth-history/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Rockets NestJS Auth History

A module for tracking authentication history and events, providing services
for creating, reading, updating and deleting auth history records. Includes
event handling for authenticated requests, repository management, and access
control.

## Project

[![NPM Latest](https://img.shields.io/npm/v/@concepta/nestjs-auth-history)](https://www.npmjs.com/package/@concepta/nestjs-auth-history)
[![NPM Downloads](https://img.shields.io/npm/dw/@conceptadev/nestjs-auth-history)](https://www.npmjs.com/package/@concepta/nestjs-auth-history)
[![GH Last Commit](https://img.shields.io/github/last-commit/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets)
[![GH Contrib](https://img.shields.io/github/contributors/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets/graphs/contributors)
[![NestJS Dep](https://img.shields.io/github/package-json/dependency-version/conceptadev/rockets/@nestjs/common?label=NestJS&logo=nestjs&filename=packages%2Fnestjs-core%2Fpackage.json)](https://www.npmjs.com/package/@nestjs/common)

## Installation

`yarn add @concepta/nestjs-auth-history`
46 changes: 46 additions & 0 deletions packages/nestjs-auth-history/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@concepta/nestjs-auth-history",
"version": "6.0.0-alpha.1",
"description": "Rockets NestJS auth history",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "BSD-3-Clause",
"publishConfig": {
"access": "public"
},
"files": [
"dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}"
],
"dependencies": {
"@concepta/nestjs-access-control": "^6.0.0-alpha.1",
"@concepta/nestjs-common": "^6.0.0-alpha.1",
"@concepta/nestjs-crud": "^6.0.0-alpha.1",
"@concepta/nestjs-event": "^6.0.0-alpha.1",
"@concepta/nestjs-exception": "^6.0.0-alpha.1",
"@concepta/nestjs-password": "^6.0.0-alpha.1",
"@concepta/nestjs-typeorm-ext": "^6.0.0-alpha.1",
"@concepta/typeorm-common": "^6.0.0-alpha.1",
"@nestjs/common": "^10.4.1",
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^10.4.1",
"@nestjs/swagger": "^7.4.0"
},
"devDependencies": {
"@concepta/nestjs-auth-jwt": "^6.0.0-alpha.1",
"@concepta/nestjs-authentication": "^6.0.0-alpha.1",
"@concepta/nestjs-jwt": "^6.0.0-alpha.1",
"@concepta/nestjs-user": "^6.0.0-alpha.1",
"@concepta/typeorm-seeding": "^4.0.0",
"@faker-js/faker": "^8.4.1",
"@nestjs/testing": "^10.4.1",
"@nestjs/typeorm": "^10.0.2",
"accesscontrol": "^2.2.1",
"supertest": "^6.3.4"
},
"peerDependencies": {
"@concepta/nestjs-auth-local": "^6.0.0-alpha.1",
"class-transformer": "*",
"class-validator": "*",
"typeorm": "^0.3.0"
}
}
Loading
Loading