jwt issuing
This commit is contained in:
parent
5769eca8ee
commit
ff431c958c
6
package-lock.json
generated
6
package-lock.json
generated
@ -2142,8 +2142,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@icynet/oauth2-provider": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git#a440d1f4ac53ccb6989dd25221797490611e240a",
|
||||
"version": "1.0.5",
|
||||
"resolved": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git#20c0771bf08cafb27809e6cdb21dbff0ae40aec3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "^4.17.3",
|
||||
@ -14155,7 +14155,7 @@
|
||||
"dev": true
|
||||
},
|
||||
"@icynet/oauth2-provider": {
|
||||
"version": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git#a440d1f4ac53ccb6989dd25221797490611e240a",
|
||||
"version": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git#20c0771bf08cafb27809e6cdb21dbff0ae40aec3",
|
||||
"from": "@icynet/oauth2-provider@git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git",
|
||||
"requires": {
|
||||
"express": "^4.17.3",
|
||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { Client } from 'connect-redis';
|
||||
import { User } from 'src/modules/objects/user/user.entity';
|
||||
|
||||
const UNPRIVILEGED_STRIP = ['openid', 'id_token', 'management', 'implicit'];
|
||||
const UNPRIVILEGED_STRIP = ['id_token', 'management', 'implicit'];
|
||||
|
||||
@Injectable()
|
||||
export class AdminService {
|
||||
|
@ -39,8 +39,8 @@ export const configProviders: Provider<any>[] = [
|
||||
},
|
||||
jwt: {
|
||||
algorithm: 'RS256',
|
||||
issuer: 'localhost',
|
||||
expiration: 3600,
|
||||
issuer: 'http://localhost',
|
||||
expiration: 604800,
|
||||
},
|
||||
database: {
|
||||
type: 'mysql',
|
||||
|
@ -56,6 +56,8 @@ export class ClientAdapter implements OAuth2ClientAdapter {
|
||||
}
|
||||
|
||||
checkScope(client: OAuth2Client, scope: string[]): boolean {
|
||||
return scope.every((one) => client.scope.includes(one));
|
||||
return scope.every(
|
||||
(one) => one === 'profile' || client.scope.includes(one),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ export class CodeAdapter implements OAuth2CodeAdapter {
|
||||
clientId: string,
|
||||
scope: string | string[],
|
||||
ttl: number,
|
||||
nonce?: string,
|
||||
): Promise<string> {
|
||||
const client = await this._service.clientService.getById(clientId);
|
||||
const user = await this._service.userService.getById(userId);
|
||||
@ -31,6 +32,7 @@ export class CodeAdapter implements OAuth2CodeAdapter {
|
||||
scopes,
|
||||
expiresAt,
|
||||
user,
|
||||
nonce,
|
||||
);
|
||||
|
||||
return accessToken;
|
||||
|
43
src/modules/oauth2/adapter/jwt.adapter.ts
Normal file
43
src/modules/oauth2/adapter/jwt.adapter.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { JWTAdapter, OAuth2User, OAuth2Client } from '@icynet/oauth2-provider';
|
||||
import { OAuth2Service } from '../oauth2.service';
|
||||
|
||||
export class IcyJWTAdapter implements JWTAdapter {
|
||||
constructor(private _client: OAuth2Service) {}
|
||||
|
||||
async issueIdToken(
|
||||
rawUser: OAuth2User,
|
||||
rawClient: OAuth2Client,
|
||||
scope: string[],
|
||||
nonce?: string,
|
||||
): Promise<string> {
|
||||
const user = await this._client.userService.getById(rawUser.id as number);
|
||||
|
||||
const userData: Record<string, unknown> = {
|
||||
name: user.display_name,
|
||||
preferred_username: user.username,
|
||||
nickname: user.display_name,
|
||||
updated_at: user.updated_at,
|
||||
nonce,
|
||||
};
|
||||
|
||||
if (scope.includes('email')) {
|
||||
userData.email = user.email;
|
||||
userData.email_verified = true;
|
||||
}
|
||||
|
||||
if (
|
||||
(scope.includes('image') || scope.includes('profile')) &&
|
||||
user.picture
|
||||
) {
|
||||
userData.picture = `${this._client.config.get('app.base_url')}/uploads/${
|
||||
user.picture.file
|
||||
}`;
|
||||
}
|
||||
|
||||
return this._client.jwt.issue(
|
||||
userData,
|
||||
user.uuid as string,
|
||||
rawClient.id as string,
|
||||
);
|
||||
}
|
||||
}
|
@ -3,10 +3,17 @@ import { OAuth2ClientModule } from 'src/modules/objects/oauth2-client/oauth2-cli
|
||||
import { OAuth2TokenModule } from 'src/modules/objects/oauth2-token/oauth2-token.module';
|
||||
import { UploadModule } from 'src/modules/objects/upload/upload.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { JWTModule } from '../jwt/jwt.module';
|
||||
import { OAuth2Service } from './oauth2.service';
|
||||
|
||||
@Module({
|
||||
imports: [UserModule, UploadModule, OAuth2ClientModule, OAuth2TokenModule],
|
||||
imports: [
|
||||
UserModule,
|
||||
UploadModule,
|
||||
OAuth2ClientModule,
|
||||
OAuth2TokenModule,
|
||||
JWTModule,
|
||||
],
|
||||
providers: [OAuth2Service],
|
||||
exports: [OAuth2Service],
|
||||
})
|
||||
|
@ -5,9 +5,11 @@ import { OAuth2ClientService } from 'src/modules/objects/oauth2-client/oauth2-cl
|
||||
import { OAuth2TokenService } from 'src/modules/objects/oauth2-token/oauth2-token.service';
|
||||
import { UserService } from 'src/modules/objects/user/user.service';
|
||||
import { TokenService } from 'src/modules/utility/services/token.service';
|
||||
import { JWTService } from '../jwt/jwt.service';
|
||||
import { AccessTokenAdapter } from './adapter/access-token.adapter';
|
||||
import { ClientAdapter } from './adapter/client.adapter';
|
||||
import { CodeAdapter } from './adapter/code.adapter';
|
||||
import { IcyJWTAdapter } from './adapter/jwt.adapter';
|
||||
import { RefreshTokenAdapter } from './adapter/refresh-token.adapter';
|
||||
import { UserAdapter } from './adapter/user.adapter';
|
||||
|
||||
@ -27,6 +29,7 @@ export class OAuth2Service {
|
||||
user: new UserAdapter(this),
|
||||
client: new ClientAdapter(this),
|
||||
code: new CodeAdapter(this),
|
||||
jwt: new IcyJWTAdapter(this),
|
||||
};
|
||||
|
||||
public oauth = new OAuth2Provider(
|
||||
@ -64,6 +67,7 @@ export class OAuth2Service {
|
||||
|
||||
constructor(
|
||||
public token: TokenService,
|
||||
public jwt: JWTService,
|
||||
public config: ConfigurationService,
|
||||
public userService: UserService,
|
||||
public clientService: OAuth2ClientService,
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
Entity,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
OneToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
@ -20,7 +20,13 @@ export class OAuth2ClientService {
|
||||
'implicit',
|
||||
];
|
||||
|
||||
public availableScopes = ['image', 'email', 'privileges', 'management'];
|
||||
public availableScopes = [
|
||||
'image',
|
||||
'email',
|
||||
'privileges',
|
||||
'management',
|
||||
'openid',
|
||||
];
|
||||
|
||||
constructor(
|
||||
@Inject('CLIENT_REPOSITORY')
|
||||
|
@ -18,6 +18,7 @@ export class OAuth2TokenService {
|
||||
scope: string,
|
||||
expiry: Date,
|
||||
user?: User,
|
||||
nonce?: string,
|
||||
): Promise<OAuth2Token> {
|
||||
const newToken = new OAuth2Token();
|
||||
newToken.client = client;
|
||||
@ -26,6 +27,7 @@ export class OAuth2TokenService {
|
||||
newToken.scope = scope;
|
||||
newToken.user = user;
|
||||
newToken.expires_at = expiry;
|
||||
newToken.nonce = nonce;
|
||||
|
||||
await this.tokenRepository.save(newToken);
|
||||
|
||||
|
Reference in New Issue
Block a user