Skip to content

Commit b3abeb8

Browse files
committed
Added typings to configuration objects on all three packages
1 parent e2c9713 commit b3abeb8

File tree

12 files changed

+139
-38
lines changed

12 files changed

+139
-38
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
],
8484
"flowtype/type-id-match": [
8585
2,
86-
"^([A-Z][a-z0-9]+)+Type$"
86+
"^([A-Z][a-z0-9]+)+"
8787
],
8888
"flowtype/union-intersection-spacing": [
8989
2,

packages/client/src/AccountsClient.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import config from './config';
1717
import createStore from './createStore';
1818
import reducer, { loggingIn, setUser, clearUser, setTokens, clearTokens as clearStoreTokens } from './module';
1919
import type { TransportInterface } from './TransportInterface';
20+
import type { TokenStorage, AccountsClientConfiguration } from './config';
2021

2122
const isValidUserObject = (user: PasswordLoginUserIdentityType) => has(user, 'user') || has(user, 'email') || has(user, 'id');
2223

@@ -26,21 +27,15 @@ const REFRESH_TOKEN = 'accounts:refreshToken';
2627
const getTokenKey = (type: string, options: Object) =>
2728
(isString(options.tokenStoragePrefix) && options.tokenStoragePrefix.length > 0 ? `${options.tokenStoragePrefix}:${type}` : type);
2829

29-
export interface TokenStorage {
30-
getItem(key: string): Promise<string>,
31-
removeItem(key: string): Promise<string>,
32-
setItem(key: string, value: string): Promise<string>
33-
}
34-
3530
export class AccountsClient {
36-
options: Object;
31+
options: AccountsClientConfiguration;
3732
transport: TransportInterface;
38-
store: Store<Map<string, any>, Object>;
33+
store: Store<Object, Object>;
3934
storage: TokenStorage;
4035

41-
constructor(options: Object, transport: TransportInterface) {
36+
constructor(options: AccountsClientConfiguration, transport: TransportInterface) {
4237
this.options = options;
43-
this.storage = options.tokenStorage;
38+
this.storage = options.tokenStorage || config.tokenStorage;
4439
if (!transport) {
4540
throw new AccountsError('A REST or GraphQL transport is required');
4641
}
@@ -51,9 +46,10 @@ export class AccountsClient {
5146
options.reduxLogger,
5247
] : [];
5348

49+
const reduxStoreKey = options.reduxStoreKey || config.reduxStoreKey;
5450
this.store = options.store || createStore({
5551
reducers: {
56-
[options.reduxStoreKey]: reducer,
52+
[reduxStoreKey]: reducer,
5753
},
5854
middleware,
5955
});
@@ -124,6 +120,7 @@ export class AccountsClient {
124120
const { accessToken, refreshToken } = await this.tokens();
125121
if (accessToken && refreshToken) {
126122
try {
123+
this.store.dispatch(loggingIn(true));
127124
const decodedRefreshToken = jwtDecode(refreshToken);
128125
const currentTime = Date.now() / 1000;
129126
// Refresh token is expired, user must sign back in
@@ -134,12 +131,14 @@ export class AccountsClient {
134131
// Request a new token pair
135132
const refreshedSession : LoginReturnType =
136133
await this.transport.refreshTokens(accessToken, refreshToken);
134+
this.store.dispatch(loggingIn(false));
137135

138136
await this.storeTokens(refreshedSession);
139137
this.store.dispatch(setTokens(refreshedSession.tokens));
140138
this.store.dispatch(setUser(refreshedSession.user));
141139
}
142140
} catch (err) {
141+
this.store.dispatch(loggingIn(false));
143142
this.clearTokens();
144143
this.clearUser();
145144
throw new AccountsError('falsy token provided');
@@ -187,7 +186,7 @@ export class AccountsClient {
187186

188187
async loginWithPassword(user: PasswordLoginUserType,
189188
password: ?string,
190-
callback?: Function): Promise<void> {
189+
callback?: Function): Promise<LoginReturnType> {
191190
if (!password || !user) {
192191
throw new AccountsError('Unrecognized options for login request', user, 400);
193192
}
@@ -202,7 +201,11 @@ export class AccountsClient {
202201
await this.storeTokens(res);
203202
this.store.dispatch(setTokens(res.tokens));
204203
this.store.dispatch(setUser(res.user));
205-
this.options.onSignedInHook();
204+
205+
if (this.options.onSignedInHook) {
206+
this.options.onSignedInHook();
207+
}
208+
206209
if (callback && isFunction(callback)) {
207210
callback(null, res);
208211
}
@@ -238,7 +241,10 @@ export class AccountsClient {
238241
if (callback && isFunction(callback)) {
239242
callback();
240243
}
241-
this.options.onSignedOutHook();
244+
245+
if (this.options.onSignedOutHook) {
246+
this.options.onSignedOutHook();
247+
}
242248
} catch (err) {
243249
if (callback && isFunction(callback)) {
244250
callback(err);
@@ -264,6 +270,7 @@ export class AccountsClient {
264270
}
265271

266272
async requestPasswordReset(email?: string): Promise<void> {
273+
if (!email) throw new AccountsError('Email must be provided');
267274
try {
268275
await this.transport.sendResetPasswordEmail(email);
269276
} catch (err) {
@@ -272,6 +279,7 @@ export class AccountsClient {
272279
}
273280

274281
async requestVerificationEmail(email?: string): Promise<void> {
282+
if (!email) throw new AccountsError('Email must be provided');
275283
try {
276284
await this.transport.sendVerificationEmail(email);
277285
} catch (err) {

packages/client/src/AccountsClient.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ describe('Accounts', () => {
494494
const error = 'something bad';
495495
Accounts.config({}, { sendResetPasswordEmail: () => Promise.reject({ message: error }) });
496496
try {
497-
await Accounts.requestPasswordReset();
497+
await Accounts.requestPasswordReset('email');
498498
throw new Error();
499499
} catch (err) {
500500
expect(err.message).toEqual(error);
@@ -515,7 +515,7 @@ describe('Accounts', () => {
515515
const error = 'something bad';
516516
Accounts.config({}, { sendVerificationEmail: () => Promise.reject({ message: error }) });
517517
try {
518-
await Accounts.requestVerificationEmail();
518+
await Accounts.requestVerificationEmail('email');
519519
throw new Error();
520520
} catch (err) {
521521
expect(err.message).toEqual(error);

packages/client/src/TransportInterface.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@ export interface TransportInterface {
1010
createUser(user: CreateUserType): Promise<string>,
1111
loginWithPassword(user: PasswordLoginUserType, password: string): Promise<LoginReturnType>,
1212
logout(accessToken: string): Promise<void>,
13-
refreshTokens(accessToken: string, refreshToken: string) : Promise<LoginReturnType>
13+
refreshTokens(accessToken: string, refreshToken: string) : Promise<LoginReturnType>,
14+
verifyEmail(token: string): Promise<void>,
15+
resetPassword(token: string, newPassword: string): Promise<void>,
16+
sendResetPasswordEmail(email: string): Promise<void>,
17+
sendVerificationEmail(email: string): Promise<void>
1418
}

packages/client/src/config.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,44 @@
1+
// @flow
2+
13
import { config as sharedConfig } from '@accounts/common';
4+
import type { AccountsCommonConfiguration } from '@accounts/common';
5+
import type { Store } from 'redux';
26
import AccountsClient from './AccountsClient';
37
import redirect from './redirect';
48

9+
export interface TokenStorage {
10+
getItem(key: string): Promise<string>,
11+
removeItem(key: string): Promise<string>,
12+
setItem(key: string, value: string): Promise<string>
13+
}
14+
15+
export type AccountsClientConfiguration = AccountsCommonConfiguration & {
16+
store?: ?Store<Object, Object>,
17+
reduxLogger?: ?Object,
18+
reduxStoreKey?: string,
19+
tokenStorage?: ?TokenStorage,
20+
server?: string,
21+
tokenStoragePrefix?: string,
22+
title?: string,
23+
requestPermissions?: Array<any>,
24+
requestOfflineToken?: Object,
25+
forceApprovalPrompt?: Object,
26+
requireEmailVerification?: boolean,
27+
loginPath?: string,
28+
signUpPath?: ?string,
29+
resetPasswordPath?: ?string,
30+
profilePath?: string,
31+
changePasswordPath?: ?string,
32+
homePath?: string,
33+
signOutPath?: string,
34+
onEnrollAccountHook?: Function,
35+
onResetPasswordHook?: Function,
36+
onVerifyEmailHook?: Function,
37+
onSignedInHook?: Function,
38+
onSignedOutHook?: Function,
39+
loginOnSignUp?: boolean
40+
};
41+
542
export default {
643
...sharedConfig,
744
store: null,

packages/client/src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// @flow
2+
import type { TokenStorage } from './config';
3+
import type { TransportInterface } from './TransportInterface';
24

35
import Accounts, { AccountsClient } from './AccountsClient';
4-
import type { TokenStorage } from './AccountsClient';
5-
import type { TransportInterface } from './TransportInterface';
66
import config from './config';
77
import reducer from './module';
88

packages/common/src/config.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
1+
// @flow
12
import { EMAIL_ONLY } from './passwordSignupFields';
2-
// eslint-disable-next-line import/no-named-as-default
3+
import type { PasswordSignupFields } from './passwordSignupFields';
34

4-
export default {
5+
export type AccountsCommonConfiguration = {
6+
siteUrl?: string,
7+
sendVerificationEmail?: boolean,
8+
sendEnrollmentEmail?: boolean,
9+
sendWelcomeEmail?: boolean,
10+
forbidClientAccountCreation?: boolean,
11+
restrictCreationByEmailDomain?: ?string,
12+
passwordResetTokenExpirationInDays?: number,
13+
passwordEnrollTokenExpirationInDays?: number,
14+
passwordSignupFields?: PasswordSignupFields,
15+
minimumPasswordLength?: number,
16+
path?: string
17+
};
18+
19+
export default ({
520
siteUrl: 'http://localhost:3000',
621
sendVerificationEmail: false,
722
sendEnrollmentEmail: false,
823
sendWelcomeEmail: false,
924
forbidClientAccountCreation: false,
1025
restrictCreationByEmailDomain: null,
11-
loginExpirationInDays: 90,
1226
passwordResetTokenExpirationInDays: 3,
1327
passwordEnrollTokenExpirationInDays: 30,
1428
passwordSignupFields: EMAIL_ONLY,
1529
minimumPasswordLength: 7,
1630
path: '/accounts',
17-
};
31+
}: AccountsCommonConfiguration);

packages/common/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as validators from './validators';
55
import { AccountsError } from './errors';
66
import toUsernameAndEmail from './toUsernameAndEmail';
77
import config from './config';
8+
import type { AccountsCommonConfiguration } from './config';
89

910
import type {
1011
UserObjectType,
@@ -24,6 +25,7 @@ export type {
2425
LoginReturnType,
2526
TokensType,
2627
SessionType,
28+
AccountsCommonConfiguration,
2729
};
2830

2931
export {

packages/common/src/passwordSignupFields.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@ export const EMAIL_ONLY = 'EMAIL_ONLY';
22
export const USERNAME_AND_EMAIL = 'USERNAME_AND_EMAIL';
33
export const USERNAME_AND_OPTIONAL_EMAIL = 'USERNAME_AND_OPTIONAL_EMAIL';
44
export const USERNAME_ONLY = 'USERNAME_ONLY';
5+
6+
export type PasswordSignupFields =
7+
EMAIL_ONLY |
8+
USERNAME_AND_EMAIL |
9+
USERNAME_AND_OPTIONAL_EMAIL |
10+
USERNAME_ONLY;

packages/common/src/validators.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const isEmail = (email: ?string) => {
1010

1111
export const validateEmail = (email: ?string): boolean => {
1212
const isValid = !isEmpty(trim(email || '')) && isEmail(email);
13-
return isValid;
13+
return Boolean(isValid);
1414
};
1515

1616
export const validatePassword = (password: ?string): boolean => {
@@ -21,5 +21,5 @@ export const validatePassword = (password: ?string): boolean => {
2121
export const validateUsername = (username: ?string): boolean => {
2222
const usernameRegex = /^[a-zA-Z][a-zA-Z0-9]*$/;
2323
const isValid = username && !isEmpty(trim(username)) && usernameRegex.test(username);
24-
return isValid;
24+
return Boolean(isValid);
2525
};

0 commit comments

Comments
 (0)