Skip to content

Commit

Permalink
Merge pull request #146 from codex-team/feat/note-settings-invitation…
Browse files Browse the repository at this point in the history
…-hash

Feat: invitation hash
  • Loading branch information
kloV148 authored Dec 5, 2023
2 parents 65931bf + 87fcd49 commit 402e2a7
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 6 deletions.
24 changes: 24 additions & 0 deletions migrations/tenant/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- Create "invitation hash" column in note_settings table
DO $$
BEGIN
IF NOT EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='note_settings' and column_name='invitation_hash')
THEN
ALTER TABLE "public"."note_settings" ADD COLUMN "invitation_hash" VARCHAR(255);
END IF;
END $$;

-- Generate invitation hash for records with NULL invitation_hash
DO $$
BEGIN
UPDATE "public"."note_settings"
SET "invitation_hash" = SUBSTRING(CAST(GEN_RANDOM_UUID() AS VARCHAR), 1, 10)
WHERE "invitation_hash" IS NULL;
END $$;

-- Makes the column 'invitation_hash' NOT NULL
DO $$
BEGIN
ALTER TABLE "public"."note_settings" ALTER COLUMN "invitation_hash" SET NOT NULL;
END $$;
10 changes: 10 additions & 0 deletions src/domain/entities/noteSettings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Invitation hash. It's used to invite users to team
*/
export type InvitationHash = string;

/**
* Notes settings entity
*/
Expand All @@ -21,6 +26,11 @@ export default interface NoteSettings {
* Is note public for everyone or only for collaborators
*/
isPublic: boolean;

/**
* Invitation hash
*/
invitationHash: InvitationHash;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/domain/service/noteSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type NoteSettingsRepository from '@repository/noteSettings.repository.js'
import type TeamRepository from '@repository/team.repository.js';
import type { MemberRole, Team, TeamMember, TeamMemberCreationAttributes } from '@domain/entities/team.js';
import type User from '@domain/entities/user.js';
import { createInvitationHash } from '@infrastructure/utils/invitationHash.js';

/**
* Service responsible for Note Settings
Expand Down Expand Up @@ -47,6 +48,7 @@ export default class NoteSettingsService {
return await this.noteSettingsRepository.addNoteSettings({
noteId: noteId,
isPublic: isPublic,
invitationHash: createInvitationHash(),
});
}

Expand Down
11 changes: 11 additions & 0 deletions src/infrastructure/utils/invitationHash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { nanoid } from 'nanoid';

/**
* Create invitation hash
* Used to invite users to team
*
* @param length - length of invitation hash
*/
export function createInvitationHash(length: number = 10): string {
return nanoid(length);
}
1 change: 1 addition & 0 deletions src/presentation/http/router/note.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('Note API', () => {
'isPublic': true,
'id': 1,
'noteId': 1,
'invitationHash': 'Hzh2hy4igf',
},
},
'accessRights': {
Expand Down
4 changes: 3 additions & 1 deletion src/presentation/http/router/noteSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('NoteSettings API', () => {
'isPublic': true,
'id': 2,
'noteId': 2,
'invitationHash': 'E2zRXv3cp-',
};

const response = await global.api?.fakeRequest({
Expand Down Expand Up @@ -201,6 +202,7 @@ describe('NoteSettings API', () => {
'noteId': 53,
'customHostname': 'codex.so',
'isPublic': false,
'invitationHash': 'FfAwyaR80C',
};

const response = await global.api?.fakeRequest({
Expand Down Expand Up @@ -279,4 +281,4 @@ describe('NoteSettings API', () => {

test.todo('Return 403 when user authorized, but not member of the team');
});
});
});
11 changes: 11 additions & 0 deletions src/repository/storage/postgres/orm/sequelize/noteSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export class NoteSettingsModel extends Model<InferAttributes<NoteSettingsModel>,
* Is note public
*/
public declare isPublic: CreationOptional<NoteSettings['isPublic']>;

/**
* Invitation hash
*/
public declare invitationHash: NoteSettings['invitationHash'];
}

/**
Expand Down Expand Up @@ -88,6 +93,10 @@ export default class NoteSettingsSequelizeStorage {
allowNull: false,
defaultValue: true,
},
invitationHash: {
type: DataTypes.STRING,
allowNull: false,
},
}, {
tableName: this.tableName,
sequelize: this.database,
Expand Down Expand Up @@ -169,12 +178,14 @@ export default class NoteSettingsSequelizeStorage {
noteId,
customHostname,
isPublic,
invitationHash,
}: NoteSettingsCreationAttributes
): Promise<NoteSettings> {
const settings = await this.model.create({
noteId,
customHostname,
isPublic,
invitationHash,
});

return settings;
Expand Down
12 changes: 8 additions & 4 deletions src/tests/test-data/notes-settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,31 @@
"id": 1,
"note_id": 1,
"custom_hostname": "codex.so",
"is_public": true
"is_public": true,
"invitation_hash": "Hzh2hy4igf"
},

{
"id": 2,
"note_id": 2,
"custom_hostname": "codex.so",
"is_public": true
"is_public": true,
"invitation_hash": "E2zRXv3cp-"
},

{
"id": 3,
"note_id": 3,
"custom_hostname": "codex.so",
"is_public": false
"is_public": false,
"invitation_hash": "Lw5kIwwo4_"
},

{
"id": 53,
"note_id": 53,
"custom_hostname": "codex.so",
"is_public": true
"is_public": true,
"invitation_hash": "FfAwyaR80C"
}
]
2 changes: 1 addition & 1 deletion src/tests/utils/insert-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async function insertNotes(db: SequelizeOrm): Promise<void> {
*/
async function insertNoteSettings(db: SequelizeOrm): Promise<void> {
for (const noteSetting of noteSettings) {
await db.connection.query(`INSERT INTO public.note_settings (id, "note_id", "custom_hostname", "is_public") VALUES (${noteSetting.id}, '${noteSetting.note_id}', '${noteSetting.custom_hostname}', ${noteSetting.is_public})`);
await db.connection.query(`INSERT INTO public.note_settings (id, "note_id", "custom_hostname", "is_public", "invitation_hash") VALUES (${noteSetting.id}, '${noteSetting.note_id}', '${noteSetting.custom_hostname}', ${noteSetting.is_public}, '${noteSetting.invitation_hash}')`);
}
}

Expand Down

0 comments on commit 402e2a7

Please sign in to comment.