Skip to content

Commit d6af217

Browse files
committed
add validatePassword option for custom password validation
Fixes #31
1 parent 2e37996 commit d6af217

File tree

5 files changed

+53
-17
lines changed

5 files changed

+53
-17
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,16 @@ graphqlAuthentication: graphqlAuthenticationConfig({
253253
});
254254
```
255255

256+
## Custom password validation
257+
258+
The users password is validated with `password.length >= 8` by default. Maybe you want stricter or less stricter validation on this. You will need to pass this option to change it:
259+
260+
```js
261+
graphqlAuthentication: graphqlAuthenticationConfig({
262+
validatePassword: value => value.length >= 10
263+
});
264+
```
265+
256266
## Writing an adapter
257267

258268
An adapter sits between GraphQL Authentication and your own ORM/database thingy. If you are using Prisma, there is already [graphql-authentication-prisma](https://github.com/Volst/graphql-authentication/tree/master/packages/graphql-authentication-prisma) for you.

packages/graphql-authentication/src/Config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ export interface IGraphqlAuthenticationConfig {
1414
user: User
1515
) => Promise<any>;
1616
adapter: GraphqlAuthenticationAdapter;
17+
validatePassword?: (value: string) => boolean;
1718
}
1819

1920
export function graphqlAuthenticationConfig(
2021
options: IGraphqlAuthenticationConfig
2122
) {
2223
const defaults = {
23-
requiredConfirmedEmailForLogin: false
24+
requiredConfirmedEmailForLogin: false,
25+
validatePassword: value => value.length >= 8
2426
};
2527
if (!options.adapter) {
2628
throw new Error(

packages/graphql-authentication/src/__tests__/mutations.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ test('signup - with existent user', async () => {
2929

3030
try {
3131
await req.request(`mutation {
32-
signup(data: {name: "Kees", email: "[email protected]", password: "testtest2"}) {
33-
token
34-
}
35-
}`);
32+
signup(data: {name: "Kees", email: "[email protected]", password: "testtest2"}) {
33+
token
34+
}
35+
}`);
3636
} catch (e) {
3737
expect(String(e)).toMatch(/User already exists with this email/);
3838
}
@@ -44,10 +44,33 @@ test('signup - with weak password', async () => {
4444

4545
try {
4646
await req.request(`mutation {
47-
signup(data: {name: "Roger", email: "[email protected]", password: "test"}) {
48-
token
49-
}
50-
}`);
47+
signup(data: {name: "Roger", email: "[email protected]", password: "test"}) {
48+
token
49+
}
50+
}`);
51+
} catch (e) {
52+
expect(String(e)).toMatch(/Password is too short/);
53+
}
54+
});
55+
56+
test('signup - with custom password validation', async () => {
57+
expect.assertions(1);
58+
const req = client(
59+
await startServer({
60+
graphqlAuthentication: {
61+
validatePassword: value => {
62+
return value.length > 400;
63+
}
64+
}
65+
})
66+
);
67+
68+
try {
69+
await req.request(`mutation {
70+
signup(data: {name: "Roger", email: "[email protected]", password: "testtest2"}) {
71+
token
72+
}
73+
}`);
5174
} catch (e) {
5275
expect(String(e)).toMatch(/Password is too short/);
5376
}

packages/graphql-authentication/src/__tests__/setup.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const AUTH_KEY =
8787
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIyIiwiaWF0IjoxNTI5MjUxNjQ4fQ.Tw4a0CI3r_8GmyuO1v2aMonrQtKV9QFYnXoxQz0cyRQ';
8888

8989
let http: any;
90-
export async function startServer() {
90+
export async function startServer(options: any = {}) {
9191
if (http) {
9292
await http.close();
9393
}
@@ -106,7 +106,8 @@ export async function startServer() {
106106
...req,
107107
graphqlAuthentication: graphqlAuthenticationConfig({
108108
secret: 'wherearemyshoes',
109-
adapter
109+
adapter,
110+
...options.graphqlAuthentication
110111
})
111112
})
112113
});

packages/graphql-authentication/src/mutations.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ function generateToken(user: User, ctx: Context) {
2929
return jwt.sign({ userId: user.id }, ctx.graphqlAuthentication.secret);
3030
}
3131

32-
function validatePassword(value: string) {
33-
if (value.length <= 8) {
32+
function validatePassword(ctx: Context, value: string) {
33+
if (!ctx.graphqlAuthentication.validatePassword!(value)) {
3434
throw new PasswordTooShortError();
3535
}
3636
}
@@ -62,7 +62,7 @@ export const mutations = {
6262
throw new InvalidInviteTokenError();
6363
}
6464

65-
validatePassword(data.password);
65+
validatePassword(ctx, data.password);
6666
const hashedPassword = await getHashedPassword(data.password);
6767

6868
const updatedUser = await ctx.graphqlAuthentication.adapter.updateUserCompleteInvite(
@@ -94,7 +94,7 @@ export const mutations = {
9494
throw new UserEmailExistsError();
9595
}
9696

97-
validatePassword(data.password);
97+
validatePassword(ctx, data.password);
9898
const hashedPassword = await getHashedPassword(data.password);
9999
const emailConfirmToken = uuid();
100100

@@ -221,7 +221,7 @@ export const mutations = {
221221
throw new InvalidOldPasswordError();
222222
}
223223

224-
validatePassword(newPassword);
224+
validatePassword(ctx, newPassword);
225225
const password = await getHashedPassword(newPassword);
226226

227227
const newUser = await ctx.graphqlAuthentication.adapter.updateUserPassword(
@@ -379,7 +379,7 @@ export const mutations = {
379379
throw new ResetTokenExpiredError();
380380
}
381381

382-
validatePassword(password);
382+
validatePassword(ctx, password);
383383
const hashedPassword = await getHashedPassword(password);
384384

385385
await ctx.graphqlAuthentication.adapter.updateUserResetToken(ctx, user.id, {

0 commit comments

Comments
 (0)