Skip to content

Commit

Permalink
Merge pull request #29 from appventure-nush/student-auth
Browse files Browse the repository at this point in the history
add authorisation frontend
  • Loading branch information
squi-ddy authored Apr 7, 2024
2 parents d76462c + 14bfcb6 commit 6dd1c8b
Show file tree
Hide file tree
Showing 19 changed files with 8,537 additions and 22,480 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
matrix:
node-version: [14.x]
node-version: [16.x]

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ts-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:

strategy:
matrix:
node-version: [14.x]
node-version: [16.x]

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:14-alpine
FROM node:16-alpine

RUN adduser -S nush-link
USER nush-link
Expand Down
18,912 changes: 4,736 additions & 14,176 deletions frontend/package-lock.json

Large diffs are not rendered by default.

28 changes: 13 additions & 15 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,20 @@
"vuex": "^3.6.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.31.2",
"@typescript-eslint/parser": "^4.31.2",
"@vue/cli-plugin-eslint": "^5.0.0-beta.4",
"@vue/cli-plugin-typescript": "^5.0.0-beta.4",
"@vue/cli-service": "^5.0.0-beta.4",
"@vue/eslint-config-airbnb": "^5.3.0",
"@vue/eslint-config-typescript": "^7.0.0",
"eslint": "^7.32.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"@vue/cli-plugin-eslint": "^5.0.0",
"@vue/cli-plugin-typescript": "^5.0.0",
"@vue/cli-service": "^5.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"eslint": "^8.0.0",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-vue": "^7.18.0",
"lint-staged": "^11.1.2",
"sass": "1.32.1",
"sass-loader": "^12.1.0",
"tslib": "^2.3.1",
"typescript": "~4.4.3",
"vue-cli-plugin-vuetify": "~2.4.2",
"eslint-plugin-vue": "^9.0.0",
"lint-staged": "^15.0.0",
"sass": "^1.32.1",
"sass-loader": "^14.1.0",
"typescript": "^5.0.0",
"vue-cli-plugin-vuetify": "^2.4.2",
"vue-template-compiler": "^2.6.14",
"vuetify-loader": "^1.7.3"
},
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@
</v-app-bar>

<!-- Show full page image on front page-->
<v-app-bar v-else app dense fixed dark shrink-on-scroll prominent fade-img-on-scroll :height="height" :src="this.img" alt class="icon" :key="this.img" :class="imgIsLoaded ? 'show,display' : 'display'" loading="lazy" @load="imgLoadedMethod">
<v-container fill-width :fill-height="!this.hideSubtitle" fluid>
<v-app-bar v-else app dense fixed dark shrink-on-scroll prominent fade-img-on-scroll :height="height" :src="img" alt class="icon" :key="img" :class="imgIsLoaded ? 'show,display' : 'display'" loading="lazy" @load="imgLoadedMethod">
<v-container fill-width :fill-height="!hideSubtitle" fluid>
<v-row align="center" justify="center">
<v-col :align="(this.hideSubtitle) ? 'left' : 'center'" justify="center">
<v-col :align="(hideSubtitle) ? 'left' : 'center'" justify="center">
<v-toolbar-title class="text-wrap" :style="{padding: 0, color: 'white', 'font-weight':500}">
<span :style="{'font-size':Math.max((width < 333?0.75:1)*this.font,1)+'em'}">{{route.name}}</span>
<span v-if="!this.hideSubtitle" class="text-wrap" :style="{'font-size':Math.min(1,this.font)+'em'}">
<span :style="{'font-size':Math.max((width < 333?0.75:1)*font,1)+'em'}">{{route.name}}</span>
<span v-if="!hideSubtitle" class="text-wrap" :style="{'font-size':Math.min(1,font)+'em'}">
<br>
An AppVenture Project
</span>
</v-toolbar-title>
<a v-if="!this.hideSubtitle" href="#" v-scroll-to="'#intro'" class="back-to-top"><v-icon>mdi-arrow-down</v-icon></a>
<a v-if="!hideSubtitle" href="#" v-scroll-to="'#intro'" class="back-to-top"><v-icon>mdi-arrow-down</v-icon></a>
</v-col>
</v-row>
</v-container>
Expand Down
Empty file removed frontend/src/components/.gitkeep
Empty file.
47 changes: 47 additions & 0 deletions frontend/src/components/AuthoriseStudentPopup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<v-card>
<!-- Loading -->
<v-card-title v-if="!success && !error">
Authorising...
<v-spacer/>
<v-progress-circular
indeterminate
color="primary"
/>
</v-card-title>
<!-- Link created -->
<v-card-title v-if="success">
Student Authorised!
<v-spacer/>
<v-btn icon color="primary" @click="$emit('close')">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<!-- Error occurred -->
<v-card-title v-if="!success && error.length">
Oops, an error occurred!
<v-spacer/>
<v-btn icon color="primary" @click="$emit('close')">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text v-if="!success && error.length">
<v-row style="font-size: 1.25em">
<v-col align="center" class="error--text">
{{ error }}
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>

<script lang="ts">
import Vue from "vue";
export default Vue.extend({
props: {
success: Boolean,
error: String,
}
});
</script>
6 changes: 3 additions & 3 deletions frontend/src/components/CreateLinkPopup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<v-row>
<v-col align="center">
<span style="font-size: 1.5em">
nush.link/{{ this.alias }}
nush.link/{{ alias }}
</span>
</v-col>
</v-row>
Expand All @@ -45,13 +45,13 @@
<v-row>
<v-col align="center">
<span style="font-size: 1.5em">
{{ this.original }}
{{ original }}
</span>
</v-col>
</v-row>
</v-col>

<v-col v-if="this.success" align="center">
<v-col v-if="success" align="center">
<qrcode-vue :value="original" :size="100" level="H" className='qrcode' id="picture" margin="20" padding="20" />
</v-col>
</v-row>
Expand Down
Empty file removed frontend/src/types/.gitkeep
Empty file.
6 changes: 3 additions & 3 deletions frontend/src/views/Links.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@
</template>
</v-data-table>
<v-btn tile @click="showDeleteSelectedDialog()" color="error"
:disabled="this.selected.length == 0">
:disabled="selected.length == 0">
<v-icon left>
mdi-delete
</v-icon>
Delete Selected
</v-btn>
<!-- delete dialog -->
<v-dialog v-model="dialogDelete" max-width="500px" v-if="this.itemToDelete">
<v-dialog v-model="dialogDelete" max-width="500px" v-if="itemToDelete">
<v-card>
<v-card-title>Delete</v-card-title>
<v-card-text>Are you sure you want to delete <a
Expand All @@ -89,7 +89,7 @@
<v-card-actions>
<v-btn color="primary" text @click="dialogDeleteAll = false">Cancel</v-btn>
<v-btn color="error" text @click="deleteSelected()"
:disabled="this.deletions.length == 0">Delete
:disabled="deletions.length == 0">Delete
</v-btn>
</v-card-actions>
</v-card>
Expand Down
127 changes: 125 additions & 2 deletions frontend/src/views/Main.vue
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@
v-model="dialog"
width="600px"
height="500"
persistent>
persistent
>
<template v-slot:activator="{ on, attrs }">
<v-btn
x-large
Expand All @@ -113,9 +114,94 @@
</v-row>
</v-col>
</v-row>

<v-row v-if="user">
<v-divider/>
</v-row>

<!-- Authorize Students -->
<v-row v-if="user && canAuthorizeStudents">
<v-col align="center" justify="center">
<span v-if="user && canAuthorizeStudents" style="font-size: 2em">
Authorise a Student!
</span><br>
<v-form
v-if="user && canAuthorizeStudents"
ref="form"
v-model="valid"
lazy-validation>
<v-row
align="center"
justify="center"
class="ma-4"
>
<v-col
cols="12"
sm="4"
>
<h3>Email</h3>
<v-text-field
x-large
v-model="student_email"
placeholder="Student Email"
:rules="[rules.email]"
required>
</v-text-field>
<v-spacer/>
</v-col>
<v-col
cols="12"
sm="4"
>
<h3>Reason</h3>
<v-text-field
x-large
v-model="student_reason"
placeholder="Reason"
required>
</v-text-field>
</v-col>
</v-row>
</v-form>
<v-row
align="center"
justify="center"
class="my-6"
>
<!-- Users can only create links when signed in -->
<!-- Make the dialog persistent to prevent accidental closure -->
<v-dialog
v-if="user && canAuthorizeStudents"
v-model="student_dialog"
width="600px"
height="500"
persistent>
<template v-slot:activator="{ on, attrs }">
<v-btn
x-large
:disabled="!valid || !student_email || student_email.length === 0"
color="primary"
v-bind="attrs"
v-on="on"
@click="authorise"
>
Authorise
</v-btn>
</template>
<authorise-student-popup
:success="student_success"
:error="student_dialog_error"
@close="resetForm"
/>
</v-dialog>
</v-row>
</v-col>
</v-row>

<v-row v-if="user">
<v-divider/>
</v-row>

<v-row
v-if="user">
<v-col align="center" justify="center">
Expand All @@ -129,17 +215,20 @@
</v-btn>
</v-col>
</v-row>

</v-container>
</template>

<script lang="ts">
import Vue from "vue";
import CreateLinkPopup from "@/components/CreateLinkPopup.vue";
import AuthoriseStudentPopup from "@/components/AuthoriseStudentPopup.vue";
export default Vue.extend({
name: "Main",
components: {
CreateLinkPopup
CreateLinkPopup,
AuthoriseStudentPopup
},
data: function () {
return {
Expand All @@ -157,6 +246,13 @@ export default Vue.extend({
return true;
}
return "Invalid Alias for the New URL";
},
email: (value: string | undefined) => {
if (value === undefined || value === "") return true;
if (value.trim().toLowerCase().match(/^h\d{7}@nushigh\.edu\.sg$/)) {
return true;
}
return "Invalid Email";
}
},
valid: true,
Expand All @@ -165,6 +261,11 @@ export default Vue.extend({
url_new_error: "",
checked_alias: "",
success: false,
student_email: "",
student_reason: "",
student_dialog: false,
student_dialog_error: "",
student_success: false,
dialog: false,
dialog_error: "",
Expand Down Expand Up @@ -205,6 +306,23 @@ export default Vue.extend({
}
});
},
authorise() {
this.student_success = false;
fetch(`/api/authorize_student`, {
method: "POST",
headers: {"Content-type": "application/json; charset=UTF-8"},
body: JSON.stringify({
student_email: this.student_email.trim(),
reason: this.student_reason.trim()
})
}).then(response => response.json()).then((data) => {
if (data.success) {
this.student_success = true;
} else if (typeof data.message !== "undefined") {
this.student_dialog_error = data.message;
}
});
},
checkAvailability() {
this.checked_alias = "";
this.url_new_error = "";
Expand Down Expand Up @@ -237,10 +355,14 @@ export default Vue.extend({
this.dialog = false;
this.url_new_error = "";
this.dialog_error = "";
this.student_dialog = false;
this.student_dialog_error = "";
},
resetForm() {
this.url_new = "";
this.url_original = "";
this.student_email = "";
this.student_reason = "";
this.resetState();
},
signIn() {
Expand All @@ -249,6 +371,7 @@ export default Vue.extend({
`redirect_uri=${location.origin}/api/auth/login&` +
`response_type=id_token&nonce=nush-link&response_mode=form_post&prompt=select_account`;
},
},
});
</script>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/views/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
</v-card-title>
<v-card-text>
<span v-if="linkData" style="font-size: 1.5em">
<a :href="'https://nush.link/'+ this.alias" target="_blank">nush.link/{{
this.alias
<a :href="'https://nush.link/'+ alias" target="_blank">nush.link/{{
alias
}}</a> points to
<a :href="this.linkData.url" target="_blank">{{ this.linkData.url }}</a>
<a :href="linkData.url" target="_blank">{{ linkData.url }}</a>
</span><br><br>
<span v-if="linkData">
Created by <b>{{linkData.creator}}</b> on <b>{{ new Date(linkData.createdOn).toLocaleDateString() }}</b>
Expand Down
Loading

0 comments on commit 6dd1c8b

Please sign in to comment.