1 | import { User, DatabaseInterface, AuthenticationService } from '@accounts/types';
|
2 | import { AccountsServer, ServerHooks } from '@accounts/server';
|
3 | import { OAuthOptions } from './types/oauth-options';
|
4 |
|
5 | export class AccountsOauth implements AuthenticationService {
|
6 | public server!: AccountsServer;
|
7 | public serviceName = 'oauth';
|
8 | private db!: DatabaseInterface;
|
9 | private options: OAuthOptions;
|
10 |
|
11 | constructor(options: OAuthOptions) {
|
12 | this.options = options;
|
13 | }
|
14 |
|
15 | public setStore(store: DatabaseInterface) {
|
16 | this.db = store;
|
17 | }
|
18 |
|
19 | public async authenticate(params: any): Promise<User | null> {
|
20 | if (!params.provider || !this.options[params.provider]) {
|
21 | throw new Error('Invalid provider');
|
22 | }
|
23 |
|
24 | const userProvider = this.options[params.provider];
|
25 |
|
26 | if (typeof userProvider.authenticate !== 'function') {
|
27 | throw new Error('Invalid provider');
|
28 | }
|
29 |
|
30 | const oauthUser = await userProvider.authenticate(params);
|
31 | let user = await this.db.findUserByServiceId(params.provider, oauthUser.id);
|
32 |
|
33 | if (!user && oauthUser.email) {
|
34 | user = await this.db.findUserByEmail(oauthUser.email);
|
35 | }
|
36 |
|
37 | if (!user) {
|
38 | try {
|
39 | const userId = await this.db.createUser({
|
40 | email: oauthUser.email,
|
41 | });
|
42 |
|
43 | user = (await this.db.findUserById(userId)) as User;
|
44 |
|
45 | if (this.server) {
|
46 | await this.server.getHooks().emit(ServerHooks.CreateUserSuccess, user);
|
47 | }
|
48 | } catch (e) {
|
49 | if (this.server) {
|
50 | await this.server.getHooks().emit(ServerHooks.CreateUserError, user);
|
51 | }
|
52 |
|
53 | throw e;
|
54 | }
|
55 | }
|
56 |
|
57 | await this.db.setService(user.id, params.provider, oauthUser);
|
58 |
|
59 | return user;
|
60 | }
|
61 |
|
62 | public async unlink(userId: string, provider: string) {
|
63 | if (!provider || !this.options[provider]) {
|
64 | throw new Error('Invalid provider');
|
65 | }
|
66 |
|
67 | await this.db.setService(userId, provider, null as any);
|
68 | }
|
69 | }
|