* create gmail strategy and controller
* gmail button connect
* wip
* trying to fix error { error: 'invalid_grant', error_description: 'Bad Request' }
* access token working
* refresh token working
* Getting the short term token from the front is working
* working
* rename token
* remove comment
* rename env var
* move file
* Fix
* Fix
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
import { PassportStrategy } from '@nestjs/passport';
|
|
import {
|
|
ForbiddenException,
|
|
Injectable,
|
|
UnauthorizedException,
|
|
} from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
|
|
import { Strategy, ExtractJwt } from 'passport-jwt';
|
|
import { Repository } from 'typeorm';
|
|
|
|
import { assert } from 'src/utils/assert';
|
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
|
import { Workspace } from 'src/core/workspace/workspace.entity';
|
|
import { User } from 'src/core/user/user.entity';
|
|
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
|
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
|
|
|
export type JwtPayload = { sub: string; workspaceId: string; jti?: string };
|
|
export type PassportUser = { user?: User; workspace: Workspace };
|
|
|
|
@Injectable()
|
|
export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
|
|
constructor(
|
|
private readonly environmentService: EnvironmentService,
|
|
private readonly typeORMService: TypeORMService,
|
|
private readonly dataSourceService: DataSourceService,
|
|
@InjectRepository(Workspace, 'core')
|
|
private readonly workspaceRepository: Repository<Workspace>,
|
|
@InjectRepository(User, 'core')
|
|
private readonly userRepository: Repository<User>,
|
|
) {
|
|
super({
|
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
ignoreExpiration: false,
|
|
secretOrKey: environmentService.getAccessTokenSecret(),
|
|
});
|
|
}
|
|
|
|
async validate(payload: JwtPayload): Promise<PassportUser> {
|
|
const workspace = await this.workspaceRepository.findOneBy({
|
|
id: payload.workspaceId ?? payload.sub,
|
|
});
|
|
|
|
if (!workspace) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
if (payload.jti) {
|
|
const dataSourceMetadata =
|
|
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
|
workspace.id,
|
|
);
|
|
|
|
const workspaceDataSource = await this.typeORMService.connectToDataSource(
|
|
dataSourceMetadata,
|
|
);
|
|
|
|
const apiKey = await workspaceDataSource?.query(
|
|
`SELECT * FROM ${dataSourceMetadata.schema}."apiKey" WHERE id = '${payload.jti}'`,
|
|
);
|
|
|
|
assert(
|
|
apiKey.length === 1 && !apiKey[0].revokedAt,
|
|
'This API Key is revoked',
|
|
ForbiddenException,
|
|
);
|
|
}
|
|
|
|
let user;
|
|
|
|
if (payload.workspaceId) {
|
|
user = await this.userRepository.findOne({
|
|
where: { id: payload.sub },
|
|
relations: ['defaultWorkspace'],
|
|
});
|
|
if (!user) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
}
|
|
|
|
return { user, workspace };
|
|
}
|
|
}
|