Skip to content

Commit 6238a5d

Browse files
authored
Merge pull request #296 from daanbreur/292-discord_integration_enabled_check
Add Discord integration checks to frontend.
2 parents b5384bd + 88aec88 commit 6238a5d

File tree

9 files changed

+92
-8
lines changed

9 files changed

+92
-8
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ALTER TABLE ctfnote.settings
2+
ADD COLUMN "discord_integration_enabled" boolean NOT NULL DEFAULT FALSE;
3+
4+
GRANT SELECT ("discord_integration_enabled") ON ctfnote.settings TO user_anonymous;
5+
REVOKE UPDATE ON ctfnote.settings FROM user_admin;
6+
GRANT UPDATE (unique_id, registration_allowed, registration_password_allowed, registration_password, registration_default_role, style, ical_password) ON ctfnote.settings TO user_admin;
7+
GRANT UPDATE ("discord_integration_enabled") ON ctfnote.settings TO user_postgraphile;
8+

api/src/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import discordHooks from "./plugins/discordHooks";
2222
import { getDiscordClient } from "./discord";
2323
import PgManyToManyPlugin from "@graphile-contrib/pg-many-to-many";
2424
import ProfileSubscriptionPlugin from "./plugins/ProfileSubscriptionPlugin";
25+
import { connectToDatabase } from "./discord/database/database";
2526

2627
function getDbUrl(role: "user" | "admin") {
2728
const login = config.db[role].login;
@@ -154,6 +155,22 @@ async function main() {
154155

155156
getDiscordClient();
156157

158+
const pgClient = await connectToDatabase(); //? maybe we should not keep this dependency in the discord folder?
159+
160+
try {
161+
const query =
162+
"UPDATE ctfnote.settings SET discord_integration_enabled = $1";
163+
const values = [config.discord.use.toLowerCase() !== "false"];
164+
await pgClient.query(query, values);
165+
} catch (error) {
166+
console.error(
167+
"Failed to set discord_integration_enabled flag in the database:",
168+
error
169+
);
170+
} finally {
171+
pgClient.release();
172+
}
173+
157174
app.listen(config.web.port, () => {
158175
//sendMessageToDiscord("CTFNote API started");
159176
console.log(`Listening on :${config.web.port}`);

front/graphql.schema.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12122,6 +12122,22 @@
1212212122
"name": "Setting",
1212312123
"description": null,
1212412124
"fields": [
12125+
{
12126+
"name": "discordIntegrationEnabled",
12127+
"description": null,
12128+
"args": [],
12129+
"type": {
12130+
"kind": "NON_NULL",
12131+
"name": null,
12132+
"ofType": {
12133+
"kind": "SCALAR",
12134+
"name": "Boolean",
12135+
"ofType": null
12136+
}
12137+
},
12138+
"isDeprecated": false,
12139+
"deprecationReason": null
12140+
},
1212512141
{
1212612142
"name": "icalPassword",
1212712143
"description": null,
@@ -12248,6 +12264,18 @@
1224812264
"description": "Represents an update to a `Setting`. Fields that are set will be updated.",
1224912265
"fields": null,
1225012266
"inputFields": [
12267+
{
12268+
"name": "discordIntegrationEnabled",
12269+
"description": null,
12270+
"type": {
12271+
"kind": "SCALAR",
12272+
"name": "Boolean",
12273+
"ofType": null
12274+
},
12275+
"defaultValue": null,
12276+
"isDeprecated": false,
12277+
"deprecationReason": null
12278+
},
1225112279
{
1225212280
"name": "icalPassword",
1225312281
"description": null,

front/src/components/CTF/Guests.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@
3333
<div v-else class="q-ml-xs"><i>No guests found.</i></div>
3434
</div>
3535
<div class="row text-h6">Sync with Discord event</div>
36-
<div class="row q-mt-sm">
36+
<div v-if="!settings.discordIntegrationEnabled" class="row q-mt-sm">
37+
<div style="width: 590px">
38+
The Discord integration is currently disabled.
39+
</div>
40+
</div>
41+
<div v-else class="row q-mt-sm">
3742
<div style="width: 590px">
3843
<discord-event-link-sync :ctf="ctf" class="col" />
3944
</div>
@@ -55,10 +60,12 @@ export default defineComponent({
5560
setup() {
5661
const team = ctfnote.profiles.injectTeam();
5762
const now = ref(new Date());
63+
const settings = ctfnote.settings.injectSettings();
5864
5965
return {
6066
now,
6167
team,
68+
settings,
6269
inviteUserToCtf: ctfnote.ctfs.useInviteUserToCtf(),
6370
uninviteUserToCtf: ctfnote.ctfs.useUninviteUserToCtf(),
6471
};

front/src/ctfnote/models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export type Settings = {
102102
registrationAllowed: boolean;
103103
registrationPasswordAllowed: boolean;
104104
style: SettingsColorMap;
105+
discordIntegrationEnabled: boolean;
105106
};
106107

107108
export type AdminSettings = Settings & {

front/src/ctfnote/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export function buildSettings(
4040
registrationAllowed: fragment.registrationAllowed ?? false,
4141
registrationPasswordAllowed: fragment.registrationPasswordAllowed ?? false,
4242
style: parseStyle(fragment.style ?? '{}'),
43+
discordIntegrationEnabled: fragment.discordIntegrationEnabled ?? false,
4344
};
4445
}
4546

front/src/generated/graphql.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,7 @@ export type SetDiscordEventLinkPayload = {
23502350

23512351
export type Setting = Node & {
23522352
__typename?: 'Setting';
2353+
discordIntegrationEnabled: Scalars['Boolean'];
23532354
icalPassword?: Maybe<Scalars['String']>;
23542355
/** A globally unique identifier. Can be used in various places throughout the system to identify this single value. */
23552356
nodeId: Scalars['ID'];
@@ -2362,6 +2363,7 @@ export type Setting = Node & {
23622363

23632364
/** Represents an update to a `Setting`. Fields that are set will be updated. */
23642365
export type SettingPatch = {
2366+
discordIntegrationEnabled?: InputMaybe<Scalars['Boolean']>;
23652367
icalPassword?: InputMaybe<Scalars['String']>;
23662368
registrationAllowed?: InputMaybe<Scalars['Boolean']>;
23672369
registrationDefaultRole?: InputMaybe<Role>;
@@ -3661,14 +3663,14 @@ export type UpdateCredentialsForCtfIdMutationVariables = Exact<{
36613663

36623664
export type UpdateCredentialsForCtfIdMutation = { __typename?: 'Mutation', updateCtfSecret?: { __typename?: 'UpdateCtfSecretPayload', ctfSecret?: { __typename?: 'CtfSecret', nodeId: string, credentials?: string | null } | null } | null };
36633665

3664-
export type SettingsInfoFragment = { __typename?: 'Setting', nodeId: string, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string };
3666+
export type SettingsInfoFragment = { __typename?: 'Setting', nodeId: string, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string, discordIntegrationEnabled: boolean };
36653667

3666-
export type AdminSettingsInfoFragment = { __typename?: 'Setting', nodeId: string, registrationPassword: string, registrationDefaultRole: Role, icalPassword?: string | null, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string };
3668+
export type AdminSettingsInfoFragment = { __typename?: 'Setting', nodeId: string, registrationPassword: string, registrationDefaultRole: Role, icalPassword?: string | null, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string, discordIntegrationEnabled: boolean };
36673669

36683670
export type GetSettingsQueryVariables = Exact<{ [key: string]: never; }>;
36693671

36703672

3671-
export type GetSettingsQuery = { __typename?: 'Query', settings?: { __typename?: 'SettingsConnection', nodes: Array<{ __typename?: 'Setting', nodeId: string, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string }> } | null };
3673+
export type GetSettingsQuery = { __typename?: 'Query', settings?: { __typename?: 'SettingsConnection', nodes: Array<{ __typename?: 'Setting', nodeId: string, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string, discordIntegrationEnabled: boolean }> } | null };
36723674

36733675
export type GetIcalPasswordQueryVariables = Exact<{ [key: string]: never; }>;
36743676

@@ -3678,15 +3680,15 @@ export type GetIcalPasswordQuery = { __typename?: 'Query', settings?: { __typena
36783680
export type GetAdminSettingsQueryVariables = Exact<{ [key: string]: never; }>;
36793681

36803682

3681-
export type GetAdminSettingsQuery = { __typename?: 'Query', settings?: { __typename?: 'SettingsConnection', nodes: Array<{ __typename?: 'Setting', nodeId: string, registrationPassword: string, registrationDefaultRole: Role, icalPassword?: string | null, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string }> } | null };
3683+
export type GetAdminSettingsQuery = { __typename?: 'Query', settings?: { __typename?: 'SettingsConnection', nodes: Array<{ __typename?: 'Setting', nodeId: string, registrationPassword: string, registrationDefaultRole: Role, icalPassword?: string | null, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string, discordIntegrationEnabled: boolean }> } | null };
36823684

36833685
export type UpdateSettingsMutationVariables = Exact<{
36843686
nodeId: Scalars['ID'];
36853687
patch: SettingPatch;
36863688
}>;
36873689

36883690

3689-
export type UpdateSettingsMutation = { __typename?: 'Mutation', updateSettingByNodeId?: { __typename?: 'UpdateSettingPayload', setting?: { __typename?: 'Setting', nodeId: string, registrationPassword: string, registrationDefaultRole: Role, icalPassword?: string | null, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string } | null } | null };
3691+
export type UpdateSettingsMutation = { __typename?: 'Mutation', updateSettingByNodeId?: { __typename?: 'UpdateSettingPayload', setting?: { __typename?: 'Setting', nodeId: string, registrationPassword: string, registrationDefaultRole: Role, icalPassword?: string | null, registrationAllowed: boolean, registrationPasswordAllowed: boolean, style: string, discordIntegrationEnabled: boolean } | null } | null };
36903692

36913693
export type TagFragment = { __typename?: 'Tag', nodeId: string, id: number, tag: string };
36923694

@@ -3955,6 +3957,7 @@ export const SettingsInfoFragmentDoc = gql`
39553957
registrationAllowed
39563958
registrationPasswordAllowed
39573959
style
3960+
discordIntegrationEnabled
39583961
}
39593962
`;
39603963
export const AdminSettingsInfoFragmentDoc = gql`
@@ -6127,6 +6130,7 @@ export const SettingsInfo = gql`
61276130
registrationAllowed
61286131
registrationPasswordAllowed
61296132
style
6133+
discordIntegrationEnabled
61306134
}
61316135
`;
61326136
export const AdminSettingsInfo = gql`

front/src/graphql/Settings.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ fragment SettingsInfo on Setting {
33
registrationAllowed
44
registrationPasswordAllowed
55
style
6+
discordIntegrationEnabled
67
}
78

89
fragment AdminSettingsInfo on Setting {

front/src/pages/Settings.vue

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,17 @@
138138
<div class="text-h6">Link your Discord account</div>
139139
</q-card-section>
140140

141-
<q-card-section class="q-pt-none q-gutter-md">
141+
<q-card-section
142+
v-if="!settings.discordIntegrationEnabled"
143+
class="q-pt-none q-gutter-md"
144+
>
145+
<div>The Discord integration is currently disabled.</div>
146+
</q-card-section>
147+
148+
<q-card-section
149+
v-if="settings.discordIntegrationEnabled"
150+
class="q-pt-none q-gutter-md"
151+
>
142152
<div v-if="me?.profile.discordId == null">
143153
Your CTFNote account is not linked to your Discord account.
144154
</div>
@@ -162,7 +172,11 @@
162172
</password-input>
163173
</q-card-section>
164174

165-
<q-card-actions align="right" class="q-px-md q-pb-md q-pt-none">
175+
<q-card-actions
176+
v-if="settings.discordIntegrationEnabled"
177+
align="right"
178+
class="q-px-md q-pb-md q-pt-none"
179+
>
166180
<q-btn
167181
v-if="me?.profile.discordId != null"
168182
label="Unlink Discord"
@@ -205,6 +219,8 @@ export default defineComponent({
205219
const profileToken: Ref<string> = ref('');
206220
const { result: profileTokenResult } = ctfnote.me.getProfileToken();
207221
222+
const settings = ctfnote.settings.injectSettings();
223+
208224
watch(
209225
profileTokenResult,
210226
(s) => {
@@ -242,6 +258,7 @@ export default defineComponent({
242258
username,
243259
description,
244260
me,
261+
settings,
245262
systemNotificationEnabled,
246263
askForNotificationPrivilege,
247264
disableSystemNotification,

0 commit comments

Comments
 (0)