Skip to content

Commit

Permalink
email is matched by nanomatch rather that regexp
Browse files Browse the repository at this point in the history
  • Loading branch information
jlarsson committed Sep 26, 2023
1 parent b3cc082 commit 418d599
Show file tree
Hide file tree
Showing 7 changed files with 524 additions and 14 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"mkdirp": "^3.0.1",
"mongodb": "^5.7.0",
"ms": "^2.1.3",
"nanomatch": "^1.2.13",
"openapi-backend": "^5.5.0",
"sharp": "^0.32.5",
"superagent": "^8.0.0",
Expand Down
8 changes: 4 additions & 4 deletions src/api-keys/request-validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('user access validation', () => {
givenApiKeys: [{ email: '[email protected]', secret: 'test-api-key' }],
givenLoginPolicies: [
{
emailPattern: '.*@user.com',
emailPattern: '*@user.com',
roles: ['canReserveAdverts', 'canCollectAdverts'],
},
],
Expand All @@ -47,7 +47,7 @@ describe('user access validation', () => {
],
givenLoginPolicies: [
{
emailPattern: '.*@user.com',
emailPattern: '*@user.com',
roles: ['canReserveAdverts', 'canCollectAdverts'],
},
],
Expand All @@ -70,7 +70,7 @@ describe('user access validation', () => {
],
givenLoginPolicies: [
{
emailPattern: '.*@user.com',
emailPattern: '*@user.com',
roles: ['canReserveAdverts', 'canCollectAdverts'],
},
],
Expand All @@ -86,7 +86,7 @@ describe('user access validation', () => {
givenApiKeys: [{ email: '[email protected]', secret: 'test-api-key' }],
givenLoginPolicies: [
{
emailPattern: '.*@noone.ever',
emailPattern: '*@noone.ever',
roles: [],
},
],
Expand Down
8 changes: 4 additions & 4 deletions src/users/tests/map-and-validate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('inMemoryUserMapper::mapAndValidate*', () => {
const settings = createInMemorySettingsService()
await loginPolicyAdapter(settings).updateLoginPolicies([
{
emailPattern: '.*@user.com',
emailPattern: '*@user.com',
roles: ['canEditOwnAdverts'],
},
])
Expand All @@ -55,12 +55,12 @@ describe('inMemoryUserMapper::mapAndValidate*', () => {
createInMemorySettingsService({
'login-policies': [
{
emailPattern: '.*@user.com',
emailPattern: '*@user.com',
roles: ['a', 'b'],
deny: true,
},
{
emailPattern: '.*',
emailPattern: '*',
roles: ['a', 'b'],
deny: false,
},
Expand All @@ -77,7 +77,7 @@ describe('inMemoryUserMapper::mapAndValidate*', () => {
createInMemorySettingsService({
'login-policies': [
{
emailPattern: '.*@others.com',
emailPattern: '*@others.com',
roles: ['a', 'b'],
deny: true,
},
Expand Down
4 changes: 2 additions & 2 deletions src/users/tests/request-validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('user access validation', () => {
givenUser: '[email protected]',
givenLoginPolicies: [
{
emailPattern: '.*@user.com',
emailPattern: '*@user.com',
roles: ['canReserveAdverts', 'canCollectAdverts'],
},
],
Expand All @@ -55,7 +55,7 @@ describe('user access validation', () => {
'user is denied when denied by pattern in login policy',
{
givenUser: '[email protected]',
givenLoginPolicies: [{ emailPattern: '.*@user.com', deny: true }],
givenLoginPolicies: [{ emailPattern: '*@user.com', deny: true }],
expectResponse: {
status: HttpStatusCodes.UNAUTHORIZED,
},
Expand Down
24 changes: 24 additions & 0 deletions src/users/tests/try-match-email.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { tryMatchEmail } from '../user-mapper'

describe('tryMatchEmail', () => {
const TestCases: [string, string, boolean][] = [
['[email protected]', '*@*', true],
['[email protected]', '*@company.com', true],
['[email protected]', '*[email protected]', true],
['[email protected]', '*.doe@*', true],
['[email protected]', '*[email protected]', false],
['[email protected]', '*@competition.com', false],
['[email protected]', '[email protected]', false],
['[email protected]', 'john.doe@*.com', true],
['[email protected]', 'john.doe@company.*', true],
['[email protected]', 'john.doe@company', false],
['[email protected]', 'john.doe@*.*', true],
['[email protected]', 'john.doe@*', true],
]

it.each(TestCases)(
'tryMatchEmail(%s, %s) => %s',
(email: string, pattern: string, expectedResult: boolean) =>
expect(tryMatchEmail(email, pattern)).toBe(expectedResult)
)
})
8 changes: 7 additions & 1 deletion src/users/user-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { loginPolicyAdapter } from '../login-policies/login-policy-adapter'
import type { LoginPolicy } from '../login-policies/types'
import { makeAdmin, normalizeRoles, rolesArrayToRoles } from '../login'

const nanomatch = require('nanomatch')

const isString = (v: any) => typeof v === 'string'
const isObject = (v: any) => v && typeof v === 'object' && !isArray(v)
const isArray = (v: any) => Array.isArray(v)
Expand All @@ -18,8 +20,12 @@ const validateHaffaUser = (user: HaffaUser | null): HaffaUser | null =>
? { id: user.id.toString(), roles: normalizeRoles(user.roles) }
: null

export const tryMatchEmail = (email: string, emailPattern: string): boolean =>
nanomatch.isMatch(email, emailPattern)

const tryMatchUserPolicy = (email: string, { emailPattern }: LoginPolicy) =>
new RegExp(`^${emailPattern}$`).test(email)
tryMatchEmail(email, emailPattern)

const matchLoginPolicies = (email: string, policies: LoginPolicy[]) =>
policies.filter(policy => tryMatchUserPolicy(email, policy))

Expand Down
Loading

0 comments on commit 418d599

Please sign in to comment.