Merge stable version before large change #16

Merged
xeovalyte merged 28 commits from dev into main 2023-02-14 15:37:45 +01:00
12 changed files with 2626 additions and 199 deletions
Showing only changes of commit 587ca2701d - Show all commits

2
frontend/.gitignore vendored
View File

@ -6,3 +6,5 @@ node_modules
.output .output
.env .env
dist dist
service-account.json

View File

@ -106,91 +106,84 @@ const getPersons = async (persons) => {
} }
const setupNotifications = () => { const setupNotifications = () => {
console.log('Initializing HomePage'); console.log('Initializing HomePage');
// Request permission to use push notifications // Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not // iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting // Android will just grant without prompting
PushNotifications.requestPermissions().then(result => { PushNotifications.requestPermissions().then(result => {
if (result.receive === 'granted') { if (result.receive === 'granted') {
// Register with Apple / Google to receive push via APNS/FCM // Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register() PushNotifications.register()
} else { } else {
toast.error('Error tijdens het registrenen van push notificaties') toast.error('Error tijdens het registrenen van push notificaties')
}
});
// On success, we should be able to receive notifications
PushNotifications.addListener('registration',
async (token) => {
// alert('Push registration success, token: ' + token.value);
registrationToken.value = token
const { error } = await useFetch('/api/subscribetotopic', {
method: 'post',
body: { topic: 'all', registrationToken: token.value }
})
if (error.value) {
console.log(error.value)
return toast.error('Error tijdens het krijgen van relateicodes')
} }
});
// On success, we should be able to receive notifications console.log('Subscribed to topic!')
PushNotifications.addListener('registration', }
(token) => { );
// alert('Push registration success, token: ' + token.value);
registrationToken.value = token
// Some issue with our setup and push will not work
PushNotifications.addListener('registrationError',
(error) => {
toast.error('Error tijdens het registreren van push notificaties')
fetch('https://api.xeovalyte.com/subscribetotopic', { console.log(error)
method: 'POST', }
headers: { );
Authorization: 'Basic WGVvdmFseXRlOmtNKjhuRXMzNTchalJlXm1KYnZrRSFOIw==',
'content-type': 'application/json'
},
body: JSON.stringify({ topic: 'all', registrationToken: token.value })
}).then(response => response.json())
.then(response => {
console.log(response)
})
.catch(err => {
console.log(err)
toast.error('Error tijdens het registreren van push notificaties')
});
}
);
// Some issue with our setup and push will not work // Show us the notification payload if the app is open on our device
PushNotifications.addListener('registrationError', PushNotifications.addListener('pushNotificationReceived',
(error) => { (notification) => {
toast.error('Error tijdens het registreren van push notificaties')
console.log(error) toast.info(`${notification.title}`, {
} onClick: () => navigateTo('/news')
); })
// Show us the notification payload if the app is open on our device }
PushNotifications.addListener('pushNotificationReceived', );
(notification) => {
toast.info(`${notification.title}`, { // Method called when tapping on a notification
onClick: () => navigateTo('/news') PushNotifications.addListener('pushNotificationActionPerformed',
}) (notification) => {
navigateTo('/news')
} }
); );
// Method called when tapping on a notification
PushNotifications.addListener('pushNotificationActionPerformed',
(notification) => {
navigateTo('/news')
}
);
} }
const registerFCM = () => { const registerFCM = () => {
getToken(messaging.value, { vapidKey: 'BI7l3nyGV6wJcFh7wrwmQ42W7RSXl46bmhXZJmDd4P-0K_JFP0ClTqjO-rr5H5DXBbmVR4kXwxFpUlo_d6cUy4Q' }).then((currentToken) => { getToken(messaging.value, { vapidKey: 'BI7l3nyGV6wJcFh7wrwmQ42W7RSXl46bmhXZJmDd4P-0K_JFP0ClTqjO-rr5H5DXBbmVR4kXwxFpUlo_d6cUy4Q' }).then(async (currentToken) => {
if (currentToken) { if (currentToken) {
console.log(currentToken) console.log(currentToken)
fetch('https://api.xeovalyte.com/subscribetotopic', {
method: 'POST', await useFetch('/api/subscribetotopic', {
headers: { method: 'post',
Authorization: 'Basic WGVvdmFseXRlOmtNKjhuRXMzNTchalJlXm1KYnZrRSFOIw==', body: { topic: 'all', registrationToken: currentToken }
'content-type': 'application/json' })
},
body: JSON.stringify({ topic: 'all', registrationToken: currentToken }) if (error.value) {
}).then(response => response.json()) console.log(error.value)
.then(response => { return toast.error('Error tijdens het registreren van push notifications')
console.log(response) }
})
.catch(err => { console.log('Subscribed to topic!')
console.log(err)
});
} else { } else {
// Show permission request UI // Show permission request UI
console.log('No registration token available. Request permission to generate one.'); console.log('No registration token available. Request permission to generate one.');

View File

@ -24,5 +24,10 @@ export default defineNuxtConfig({
{ rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' } { rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' }
] ]
} }
},
runtimeConfig: {
privateKeyId: '',
privateKey: '',
clientId: ''
} }
}) })

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
"@vueuse/firebase": "^9.2.0", "@vueuse/firebase": "^9.2.0",
"@vueuse/shared": "^9.4.0", "@vueuse/shared": "^9.4.0",
"firebase": "^9.14.0", "firebase": "^9.14.0",
"firebase-admin": "^11.4.1",
"vue-toastification": "^2.0.0-rc.5" "vue-toastification": "^2.0.0-rc.5"
} }
} }

View File

@ -24,7 +24,7 @@ definePageMeta({
key: 'back' key: 'back'
}) })
const { news, userData, db, auth } = inject('firebase') const { news, db, auth } = inject('firebase')
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@ -36,53 +36,45 @@ const form = ref({
}) })
const sendNews = async () => { const sendNews = async () => {
disableButtons.value = true disableButtons.value = true
try { try {
const idToken = await auth.value.currentUser.getIdToken(true) const idToken = await auth.value.currentUser.getIdToken(true)
console.log(idToken) console.log(idToken)
const { error } = await useFetch('/api/sendmessage', {
method: 'post',
body: { title: form.value.title, body: form.value.description, token: idToken }
})
await fetch('https://api.xeovalyte.com/sendmessage', { if (error.value) {
method: 'POST', console.log(error.value)
headers: { return toast.error('Error tijdens het versturen van het bericht')
Authorization: 'Basic WGVvdmFseXRlOmtNKjhuRXMzNTchalJlXm1KYnZrRSFOIw==',
'content-type': 'application/json'
},
body: JSON.stringify({ title: form.value.title, body: form.value.description, token: idToken })
}).then(response => response.json())
.then(async response => {
console.log(response)
await addDoc(collection(db, "news"), {
title: form.value.title,
description: form.value.description,
date: serverTimestamp()
});
if (news.value) {
news.value.unshift({
title: form.value.title,
description: form.value.description,
date: Timestamp.now()
})
}
toast.success('Bericht is verstuurd')
navigateTo('/news')
})
.catch(err => {
console.log(err)
toast.error('Error tijdens het berict sturen')
});
} catch (e) {
console.log(e)
toast.error('Error tijdens het berict sturen')
} }
disableButtons.value = false await addDoc(collection(db, "news"), {
title: form.value.title,
description: form.value.description,
date: serverTimestamp()
});
if (news.value) {
news.value.unshift({
title: form.value.title,
description: form.value.description,
date: Timestamp.now()
})
}
toast.success('Bericht is verstuurd')
navigateTo('/news')
} catch (e) {
console.log(e)
toast.error('Error tijdens het berict sturen')
}
disableButtons.value = false
} }
</script> </script>

View File

@ -30,7 +30,7 @@ definePageMeta({
key: 'back' key: 'back'
}) })
const { user, userAllPersons, userPersons, db, getPersons } = inject('firebase') const { user, userAllPersons, userPersons, db, getPersons, auth } = inject('firebase')
const toast = useToast() const toast = useToast()
const buttonsDisabled = ref(false) const buttonsDisabled = ref(false)
@ -50,24 +50,24 @@ onMounted(() => {
}) })
const save = async () => { const save = async () => {
buttonsDisabled.value = true buttonsDisabled.value = true
const newRelatiecodes = [] const newRelatiecodes = []
userAllPersons.value.forEach(person => { userAllPersons.value.forEach(person => {
if (person.checked) { if (person.checked) {
newRelatiecodes.push(person.relatiecode) newRelatiecodes.push(person.relatiecode)
} }
}) })
await updateDoc(doc(db, "users", user.value.uid), { await updateDoc(doc(db, "users", user.value.uid), {
relatiecodes: newRelatiecodes relatiecodes: newRelatiecodes
}) })
getPersons(newRelatiecodes) getPersons(newRelatiecodes)
buttonsDisabled.value = false buttonsDisabled.value = false
navigateTo('/settings') navigateTo('/settings')
} }
const updateCheckbox = (person) => { const updateCheckbox = (person) => {
@ -76,31 +76,30 @@ const updateCheckbox = (person) => {
person.checked = !person.checked person.checked = !person.checked
} }
const getAllPersons = () => { const getAllPersons = async () => {
if (userPersons.value.length === 0) return setTimeout(() => getAllPersons(), 50) if (userPersons.value.length === 0) return setTimeout(() => getAllPersons(), 50)
fetch('https://api.xeovalyte.com/getrelatiecodes', {
method: 'POST',
headers: {
Authorization: 'Basic WGVvdmFseXRlOmtNKjhuRXMzNTchalJlXm1KYnZrRSFOIw==',
'content-type': 'application/json'
},
body: JSON.stringify({ email: user.value.email })
}).then(response => response.json())
.then(response => {
response.persons.forEach(person => {
if (userPersons.value.map(a => a.relatiecode).includes(person.relatiecode)) {
person.checked = true
} else {
person.checked = false
}
})
userAllPersons.value = response.persons const idToken = await auth.value.currentUser.getIdToken(true)
})
.catch(err => {
console.log(err)
toast.error('Error tijdens het ophalen van gegevens')
}); const { data: response, error } = await useFetch('/api/getrelatiecodes', {
method: 'post',
body: { email: user.value.email, token: idToken }
})
if (error.value) {
console.log(error.value)
return toast.error('Error tijdens het krijgen van relateicodes')
}
response.value.persons.forEach(person => {
if (userPersons.value.map(a => a.relatiecode).includes(person.relatiecode)) {
person.checked = true
} else {
person.checked = false
}
})
userAllPersons.value = response.value.persons
} }
</script> </script>

View File

@ -0,0 +1,26 @@
import { db } from '../utils/firebase'
export default defineEventHandler(async event => {
const { relatiecode, email } = await readBody(event);
if (!relatiecode) throw createError({ statusCode: 400, statusMessage: 'no-relatiecode'})
if (!email) throw createError({ statusCode: 400, statusMessage: 'no-email'})
try {
const docRef = db.collection('ledenlijst').doc(relatiecode);
const doc = await docRef.get();
if (!doc.exists) throw createError({ statusCode: 400, statusMessage: 'incorrect'})
const data = doc.data()
if (data.email[0] === email || data.email[1] === email) {
return { code: 'correct' }
} else {
throw createError({ statusCode: 400, statusMessage: 'incorrect'})
}
} catch (e) {
throw createError({ statusCode: 500, statusMessage: e.message })
}
})

View File

@ -0,0 +1,40 @@
import { db } from '../utils/firebase'
import { getAuth } from 'firebase-admin/auth'
export default defineEventHandler(async event => {
const { email, token } = await readBody(event);
if (!email) throw createError({ statusCode: 400, statusMessage: 'no-email'})
if (!token) throw createError({ statusCode: 400, statusMessage: 'no-token'})
try {
await getAuth().verifyIdToken(token)
} catch (e) {
console.log(e);
throw createError({ statusCode: 500, statusMessage: 'error-verify-id'})
}
try {
const ledenlijstRef = db.collection('ledenlijst')
const snapshot = await ledenlijstRef.where("email", "array-contains", email).get()
if (snapshot.empty) {
throw createError({ statusCode: 400, statusMessage: 'no-relatiecode'})
}
let relatiecodes = [];
let persons = [];
snapshot.forEach(doc => {
relatiecodes.push(doc.id)
const data = doc.data()
persons.push({ fullName: data.fullName, relatiecode: doc.id })
});
return { code: 'success', relatiecodes: relatiecodes, persons: persons }
} catch (e) {
throw createError({ statusCode: 500, statusMessage: e.message })
}
})

View File

@ -0,0 +1,63 @@
import { db } from '../utils/firebase'
import { getAuth } from 'firebase-admin/auth'
import { getMessaging } from 'firebase-admin/messaging'
export default defineEventHandler(async event => {
const { token, body, title } = await readBody(event);
if (!token) throw createError({ statusCode: 400, statusMessage: 'no-token'})
if (!body) throw createError({ statusCode: 400, statusMessage: 'no-body'})
if (!title) throw createError({ statusCode: 400, statusMessage: 'no-title'})
let decodedToken = null;
try {
decodedToken = await getAuth().verifyIdToken(token)
} catch (e) {
console.log(e)
throw createError({ statusCode: 500, statusMessage: 'error-verify-id'})
}
if (!decodedToken) throw createError({ statusCode: 500, statusMessage: 'error-verify-id-test'})
try {
const uid = decodedToken.uid;
const docRef = db.collection('users').doc(uid);
const doc = await docRef.get();
if (!doc.exists) throw createError({ statusCode: 500, statusMessage: 'doc-not-found'})
const data = doc.data()
if (!data.sendNews) throw createError({ statusCode: 500, statusMessage: 'no-permissions'})
const message = {
notification: {
title: title,
body: body,
},
webpush: {
notification: {
icon: '/ios/256.png'
}
},
topic: 'test',
apns: {
payload: {
aps: {
sound: 'default'
}
}
}
};
const response = await getMessaging().send(message)
console.log('Successfully sent message:', response);
return { code: 'success', response: response }
} catch (e) {
throw createError({ statusCode: 500, statusMessage: e.message })
}
})

View File

@ -0,0 +1,19 @@
import { getMessaging } from 'firebase-admin/messaging'
export default defineEventHandler(async event => {
const { topic, registrationToken } = await readBody(event);
if (!topic) throw createError({ statusCode: 400, statusMessage: 'no-topic'})
if (!registrationToken) throw createError({ statusCode: 400, statusMessage: 'no-registrationtoken'})
try {
await getMessaging().subscribeToTopic([registrationToken], topic)
return { code: 'success'}
} catch (e) {
console.log(e)
throw createError({ statusCode: 500, statusMessage: e.message })
}
})

View File

@ -0,0 +1,25 @@
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const admin = require("firebase-admin");
import { getFirestore } from 'firebase-admin/firestore';
const config = useRuntimeConfig()
export const app = admin.initializeApp({
credential: admin.credential.cert({
"project_id": "wrbapp",
"private_key_id": config.privateKeyId,
"private_key": config.privateKey,
"client_email": "firebase-adminsdk-iqgyy@wrbapp.iam.gserviceaccount.com",
"client_id": config.clientId,
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-iqgyy%40wrbapp.iam.gserviceaccount.com"
})
})
export const firestore = getFirestore()
export const db = getFirestore();