Skip to content

Commit

Permalink
fix: regression for usernames with full stops in
Browse files Browse the repository at this point in the history
The change introduced in ece63ba to separate Username and Sub meant that
usernames with full stops in stopped working with StormDB, as it
interpreted the full stop as a path separator.

This updates our use of StormDB so it doesn't parse the keys for
separators.

Fixes jagregory#35
  • Loading branch information
jagregory committed Jul 29, 2021
1 parent 1ade4bf commit 73cb644
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 122 deletions.
16 changes: 14 additions & 2 deletions integration-tests/dataStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ describe("Data Store", () => {
});
});

it("saves a nested value", async () => {
it("saves a nested value using array syntax", async () => {
const dataStore = await createDataStore("example", {}, path);

await dataStore.set("key.a.b", 1);
await dataStore.set(["key", "a", "b"], 1);

const file = JSON.parse(await readFile(path + "/example.json", "utf-8"));

Expand All @@ -72,6 +72,18 @@ describe("Data Store", () => {
});
});

it("saves a key with dots in as a single key-value pair", async () => {
const dataStore = await createDataStore("example", {}, path);

await dataStore.set("key.a.b", 1);

const file = JSON.parse(await readFile(path + "/example.json", "utf-8"));

expect(file).toEqual({
"key.a.b": 1,
});
});

it("replaces a value", async () => {
const dataStore = await createDataStore("example", {}, path);

Expand Down
242 changes: 124 additions & 118 deletions integration-tests/userPoolClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const mkdtemp = promisify(fs.mkdtemp);
const readFile = promisify(fs.readFile);
const rmdir = promisify(fs.rmdir);

const validUsernameExamples = ["ExampleUsername", "example.username"];

describe("User Pool Client", () => {
let path: string;
let tmpCreateDataStore: CreateDataStore;
Expand Down Expand Up @@ -45,149 +47,153 @@ describe("User Pool Client", () => {
});

describe("saveUser", () => {
it("saves the user", async () => {
const now = new Date().getTime();
const userPool = await cognitoClient.getUserPool("local");
describe.each(validUsernameExamples)("with username %s", (username) => {
it("saves the user", async () => {
const now = new Date().getTime();
const userPool = await cognitoClient.getUserPool("local");

await userPool.saveUser({
Username: "1",
Password: "hunter3",
UserStatus: "UNCONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
});
await userPool.saveUser({
Username: username,
Password: "hunter3",
UserStatus: "UNCONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
});

const file = JSON.parse(await readFile(path + "/local.json", "utf-8"));
const file = JSON.parse(await readFile(path + "/local.json", "utf-8"));

expect(file).toEqual({
Options: { Id: "local", UsernameAttributes: [] },
Users: {
"1": {
Username: "1",
Password: "hunter3",
UserStatus: "UNCONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
expect(file).toEqual({
Options: { Id: "local", UsernameAttributes: [] },
Users: {
[username]: {
Username: username,
Password: "hunter3",
UserStatus: "UNCONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
},
},
},
});
});
});

it("updates a user", async () => {
const now = new Date().getTime();
const userPool = await cognitoClient.getUserPool("local");
it("updates a user", async () => {
const now = new Date().getTime();
const userPool = await cognitoClient.getUserPool("local");

await userPool.saveUser({
Username: "1",
Password: "hunter3",
UserStatus: "UNCONFIRMED",
ConfirmationCode: "1234",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
});
await userPool.saveUser({
Username: username,
Password: "hunter3",
UserStatus: "UNCONFIRMED",
ConfirmationCode: "1234",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
});

let file = JSON.parse(await readFile(path + "/local.json", "utf-8"));
let file = JSON.parse(await readFile(path + "/local.json", "utf-8"));

expect(file).toEqual({
Options: { Id: "local", UsernameAttributes: [] },
Users: {
"1": {
Username: "1",
Password: "hunter3",
UserStatus: "UNCONFIRMED",
ConfirmationCode: "1234",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
expect(file).toEqual({
Options: { Id: "local", UsernameAttributes: [] },
Users: {
[username]: {
Username: username,
Password: "hunter3",
UserStatus: "UNCONFIRMED",
ConfirmationCode: "1234",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
},
},
},
});
});

await userPool.saveUser({
Username: "1",
Password: "hunter3",
UserStatus: "CONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
});
await userPool.saveUser({
Username: username,
Password: "hunter3",
UserStatus: "CONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
});

file = JSON.parse(await readFile(path + "/local.json", "utf-8"));
file = JSON.parse(await readFile(path + "/local.json", "utf-8"));

expect(file).toEqual({
Options: { Id: "local", UsernameAttributes: [] },
Users: {
"1": {
Username: "1",
Password: "hunter3",
UserStatus: "CONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
expect(file).toEqual({
Options: { Id: "local", UsernameAttributes: [] },
Users: {
[username]: {
Username: username,
Password: "hunter3",
UserStatus: "CONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
],
UserLastModifiedDate: now,
UserCreateDate: now,
Enabled: true,
},
},
},
});
});
});
});

describe("getUserByUsername", () => {
let userPool: UserPoolClient;
beforeAll(async () => {
userPool = await cognitoClient.getUserPool("local");
describe.each(validUsernameExamples)("with username %s", (username) => {
let userPool: UserPoolClient;
beforeAll(async () => {
userPool = await cognitoClient.getUserPool("local");

await userPool.saveUser({
Username: "1",
Password: "hunter2",
UserStatus: "UNCONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
{ Name: "phone_number", Value: "0411000111" },
],
UserCreateDate: new Date().getTime(),
UserLastModifiedDate: new Date().getTime(),
Enabled: true,
await userPool.saveUser({
Username: username,
Password: "hunter2",
UserStatus: "UNCONFIRMED",
Attributes: [
{ Name: "sub", Value: "uuid-1234" },
{ Name: "email", Value: "[email protected]" },
{ Name: "phone_number", Value: "0411000111" },
],
UserCreateDate: new Date().getTime(),
UserLastModifiedDate: new Date().getTime(),
Enabled: true,
});
});
});

it("returns null if user doesn't exist", async () => {
const user = await userPool.getUserByUsername("invalid");
it("returns null if user doesn't exist", async () => {
const user = await userPool.getUserByUsername("invalid");

expect(user).toBeNull();
});
expect(user).toBeNull();
});

it("returns existing user by their sub attribute", async () => {
const user = await userPool.getUserByUsername("1");
it("returns existing user by their username", async () => {
const user = await userPool.getUserByUsername(username);

expect(user).not.toBeNull();
expect(user?.Username).toEqual("1");
expect(user).not.toBeNull();
expect(user?.Username).toEqual(username);
});
});
});

Expand Down
5 changes: 3 additions & 2 deletions src/services/dataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ export const createDataStore: CreateDataStore = async (
async get(key: string | string[], defaultValue?: unknown) {
return (
(await (key instanceof Array ? key : [key])
.reduce((acc, k) => acc.get(k), db)
.reduce((acc, k) => acc.get([k]), db)
.value()) ??
defaultValue ??
null
);
},

async set(key, value) {
await db.set(key instanceof Array ? key.join(".") : key, value).save();
db.setValue(value, key instanceof Array ? key : [key]);
await db.save();
},
};
};

0 comments on commit 73cb644

Please sign in to comment.