add ability to auth using api key
This commit is contained in:
parent
c68360c81f
commit
db7b02b629
|
@ -41,6 +41,7 @@
|
|||
"ms": "^2.1.3",
|
||||
"p-timeout": "^6.0.0",
|
||||
"passport": "^0.6.0",
|
||||
"passport-headerapikey": "^1.2.2",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"passport-strategy": "^1.0.0",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
import { PassportModule } from '@nestjs/passport';
|
||||
import { ApiKeyDbModule } from '../../collections/apikey-db/apikey-db.module';
|
||||
import { PreferenceDbModule } from '../../collections/preference-db/preference-db.module';
|
||||
import { UserDbModule } from '../../collections/user-db/user-db.module';
|
||||
import {
|
||||
|
@ -9,6 +10,7 @@ import {
|
|||
} from '../../config/late/jwt.config.service';
|
||||
import { LateConfigModule } from '../../config/late/late-config.module';
|
||||
import { AuthManagerService } from './auth.service';
|
||||
import { ApiKeyStrategy } from './guards/apikey.strategy';
|
||||
import { GuestStrategy } from './guards/guest.strategy';
|
||||
import { JwtStrategy } from './guards/jwt.strategy';
|
||||
import { LocalAuthStrategy } from './guards/local-auth.strategy';
|
||||
|
@ -19,6 +21,7 @@ import { GuestService } from './guest.service';
|
|||
UserDbModule,
|
||||
PassportModule,
|
||||
PreferenceDbModule,
|
||||
ApiKeyDbModule,
|
||||
LateConfigModule,
|
||||
JwtModule.registerAsync({
|
||||
useExisting: JwtConfigService,
|
||||
|
@ -31,6 +34,7 @@ import { GuestService } from './guest.service';
|
|||
JwtStrategy,
|
||||
GuestStrategy,
|
||||
JwtSecretProvider,
|
||||
ApiKeyStrategy,
|
||||
GuestService,
|
||||
],
|
||||
exports: [UserDbModule, AuthManagerService],
|
||||
|
|
62
backend/src/managers/auth/guards/apikey.strategy.ts
Normal file
62
backend/src/managers/auth/guards/apikey.strategy.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
|
||||
import { EUser, EUserSchema } from 'picsur-shared/dist/entities/user.entity';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { IsApiKey } from 'picsur-shared/dist/validators/api-key.validator';
|
||||
import { ApiKeyDbService } from '../../../collections/apikey-db/apikey-db.service';
|
||||
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
||||
|
||||
@Injectable()
|
||||
export class ApiKeyStrategy extends PassportStrategy(
|
||||
HeaderAPIKeyStrategy,
|
||||
'apikey',
|
||||
) {
|
||||
private readonly logger = new Logger(ApiKeyStrategy.name);
|
||||
|
||||
constructor(private readonly apikeyDB: ApiKeyDbService) {
|
||||
super(
|
||||
{
|
||||
header: 'Authorization',
|
||||
prefix: 'Api-Key ',
|
||||
},
|
||||
false,
|
||||
(
|
||||
apikey: string,
|
||||
verified: (err: Error | null, user?: Object, info?: Object) => void,
|
||||
) => {
|
||||
this.validate(apikey)
|
||||
.then((user) => {
|
||||
verified(null, user === false ? undefined : user);
|
||||
})
|
||||
.catch((err) => {
|
||||
verified(err, undefined);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async validate(apikey: string): Promise<EUser | false> {
|
||||
const apiValidation = await IsApiKey().safeParseAsync(apikey);
|
||||
if (!apiValidation.success) {
|
||||
this.logger.warn('Invalid apikey format: ' + apikey);
|
||||
return false;
|
||||
}
|
||||
|
||||
const apikeyResult = await this.apikeyDB.resolve(apikey);
|
||||
if (HasFailed(apikeyResult)) {
|
||||
this.logger.warn('Invalid apikey: ' + apikey);
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = EUserBackend2EUser(apikeyResult.user);
|
||||
|
||||
const userValidation = await EUserSchema.safeParseAsync(user);
|
||||
if (!userValidation.success) {
|
||||
this.logger.error('Invalid user: ' + JSON.stringify(user));
|
||||
return false;
|
||||
}
|
||||
|
||||
return userValidation.data;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import { isPermissionsArray } from '../../../models/validators/permissions.valid
|
|||
// This way a user will get his own account when logged in, but received guest permissions when not
|
||||
|
||||
@Injectable()
|
||||
export class MainAuthGuard extends AuthGuard(['jwt', 'guest']) {
|
||||
export class MainAuthGuard extends AuthGuard(['apikey', 'jwt', 'guest']) {
|
||||
private readonly logger = new Logger(MainAuthGuard.name);
|
||||
|
||||
constructor(
|
||||
|
|
|
@ -20,10 +20,6 @@ export class ExperimentController {
|
|||
@Request() req: AuthFasityRequest,
|
||||
@ReqUserID() thing: string,
|
||||
): Promise<UserInfoResponse> {
|
||||
const key = await this.apikeyDB.findOne("0SB7nCIkfhnAmf3Glejf0naUbI7dimhh", undefined);
|
||||
|
||||
console.log(key);
|
||||
|
||||
return req.user;
|
||||
}
|
||||
}
|
||||
|
|
11
yarn.lock
11
yarn.lock
|
@ -8741,6 +8741,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"passport-headerapikey@npm:^1.2.2":
|
||||
version: 1.2.2
|
||||
resolution: "passport-headerapikey@npm:1.2.2"
|
||||
dependencies:
|
||||
lodash: ^4.17.15
|
||||
passport-strategy: ^1.0.0
|
||||
checksum: 509b0d72225845fcb4d6a95acd76f98042bdee256bf11731ece2c8be8341235013f2150207148d7e8ed939e28857dea18503969842ad40bba7a9724396b94481
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"passport-jwt@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "passport-jwt@npm:4.0.0"
|
||||
|
@ -8991,6 +9001,7 @@ __metadata:
|
|||
ms: ^2.1.3
|
||||
p-timeout: ^6.0.0
|
||||
passport: ^0.6.0
|
||||
passport-headerapikey: ^1.2.2
|
||||
passport-jwt: ^4.0.0
|
||||
passport-local: ^1.0.0
|
||||
passport-strategy: ^1.0.0
|
||||
|
|
Loading…
Reference in a new issue