2022-03-09 18:37:04 +00:00
|
|
|
import { OAuth2AdapterModel, OAuth2Provider } from '@icynet/oauth2-provider';
|
|
|
|
import { Injectable } from '@nestjs/common';
|
2022-08-17 18:56:47 +00:00
|
|
|
import { ConfigurationService } from 'src/modules/config/config.service';
|
2022-03-09 18:37:04 +00:00
|
|
|
import { OAuth2ClientService } from 'src/modules/objects/oauth2-client/oauth2-client.service';
|
|
|
|
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 { AccessTokenAdapter } from './adapter/access-token.adapter';
|
|
|
|
import { ClientAdapter } from './adapter/client.adapter';
|
|
|
|
import { CodeAdapter } from './adapter/code.adapter';
|
|
|
|
import { RefreshTokenAdapter } from './adapter/refresh-token.adapter';
|
|
|
|
import { UserAdapter } from './adapter/user.adapter';
|
|
|
|
|
2022-03-16 18:37:50 +00:00
|
|
|
const SCOPE_DESCRIPTION: Record<string, string> = {
|
|
|
|
email: 'Email address',
|
|
|
|
image: 'Profile picture',
|
|
|
|
};
|
|
|
|
|
|
|
|
const ALWAYS_AVAILABLE = ['Username and display name'];
|
|
|
|
const ALWAYS_UNAVAILABLE = ['Password and other account settings'];
|
|
|
|
|
2022-03-09 18:37:04 +00:00
|
|
|
@Injectable()
|
|
|
|
export class OAuth2Service {
|
|
|
|
private _oauthAdapter: OAuth2AdapterModel = {
|
|
|
|
accessToken: new AccessTokenAdapter(this),
|
|
|
|
refreshToken: new RefreshTokenAdapter(this),
|
|
|
|
user: new UserAdapter(this),
|
|
|
|
client: new ClientAdapter(this),
|
|
|
|
code: new CodeAdapter(this),
|
|
|
|
};
|
|
|
|
|
2022-03-16 18:37:50 +00:00
|
|
|
public oauth = new OAuth2Provider(
|
|
|
|
this._oauthAdapter,
|
2022-03-20 17:05:21 +00:00
|
|
|
async (req, res, client, scope) => {
|
2022-03-16 18:37:50 +00:00
|
|
|
const fullClient = await this.clientService.getById(client.id as string);
|
2022-08-28 13:17:15 +00:00
|
|
|
let allowedScopes = [...ALWAYS_AVAILABLE];
|
2022-08-27 10:53:37 +00:00
|
|
|
let disallowedScopes = [...ALWAYS_UNAVAILABLE];
|
2022-03-16 18:37:50 +00:00
|
|
|
|
|
|
|
Object.keys(SCOPE_DESCRIPTION).forEach((item) => {
|
|
|
|
if (scope.includes(item)) {
|
|
|
|
allowedScopes.push(SCOPE_DESCRIPTION[item]);
|
|
|
|
} else {
|
|
|
|
disallowedScopes.push(SCOPE_DESCRIPTION[item]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-08-27 10:53:37 +00:00
|
|
|
if (scope.includes('management')) {
|
2022-08-28 13:17:15 +00:00
|
|
|
allowedScopes = [
|
|
|
|
'Manage Icy Network on your behalf',
|
|
|
|
'Commit administrative actions to the extent of your user privileges',
|
2022-08-27 10:53:37 +00:00
|
|
|
];
|
2022-08-28 13:17:15 +00:00
|
|
|
disallowedScopes = null;
|
2022-08-27 10:53:37 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 18:37:50 +00:00
|
|
|
res.render('authorize', {
|
2022-03-20 17:05:21 +00:00
|
|
|
csrf: req.csrfToken(),
|
2022-03-16 18:37:50 +00:00
|
|
|
user: req.user,
|
|
|
|
client: fullClient,
|
|
|
|
allowedScopes,
|
|
|
|
disallowedScopes,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
);
|
2022-03-09 18:37:04 +00:00
|
|
|
|
|
|
|
constructor(
|
|
|
|
public token: TokenService,
|
2022-08-17 18:56:47 +00:00
|
|
|
public config: ConfigurationService,
|
2022-03-09 18:37:04 +00:00
|
|
|
public userService: UserService,
|
|
|
|
public clientService: OAuth2ClientService,
|
|
|
|
public tokenService: OAuth2TokenService,
|
|
|
|
) {
|
2022-09-15 16:21:05 +00:00
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
|
|
this.oauth.logger.setLogLevel('debug');
|
|
|
|
}
|
2022-03-09 18:37:04 +00:00
|
|
|
}
|
|
|
|
|
2022-03-20 14:50:12 +00:00
|
|
|
public splitScope(scope: string | string[]): string[] {
|
2022-03-16 18:37:50 +00:00
|
|
|
if (!scope) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2022-03-20 14:50:12 +00:00
|
|
|
if (Array.isArray(scope)) {
|
|
|
|
return scope;
|
|
|
|
}
|
|
|
|
|
2022-03-09 18:37:04 +00:00
|
|
|
return scope.includes(',')
|
|
|
|
? scope.split(',').map((item) => item.trim())
|
|
|
|
: scope.split(' ');
|
|
|
|
}
|
|
|
|
}
|