• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kiva / ui / 21733777331

06 Feb 2026 12:21AM UTC coverage: 91.242% (-0.2%) from 91.482%
21733777331

push

github

web-flow
Merge pull request #6635 from kiva/CIT-3802

feat: image upload functionality

4015 of 4318 branches covered (92.98%)

Branch coverage included in aggregate %.

0 of 69 new or added lines in 1 file covered. (0.0%)

20363 of 22400 relevant lines covered (90.91%)

74.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/composables/useImageUpload.js
NEW
1
import { ref } from 'vue';
×
2

NEW
3
const ALLOWED_TYPES = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
×
4

NEW
5
/**
×
NEW
6
 * Composable for uploading images to /img/upload. In local dev (e.g. app at kiva-ui.local), a relative
×
NEW
7
 * /img/upload would hit the UI server and return HTML. So we send the upload to the app host URL instead
×
NEW
8
 * (e.g. https://www.development.kiva.org/img/upload) so it reaches the backend and returns JSON.
×
NEW
9
 *
×
NEW
10
 * @param {Object} kvAuth0 - Auth0 instance (injected in components that need it)
×
NEW
11
 * @param {string} [appHost] - App host from config (e.g. www.development.kiva.org). Used when current origin differs.
×
NEW
12
 * @returns {{ uploadImage: Function, uploadingImage: Ref<boolean>, uploadError: Ref<string> }}
×
NEW
13
 */
×
NEW
14
export default function useImageUpload(kvAuth0, appHost = '') {
×
NEW
15
        const uploadingImage = ref(false);
×
NEW
16
        const uploadError = ref('');
×
17

NEW
18
        const uploadImage = async file => {
×
NEW
19
                if (!kvAuth0) {
×
NEW
20
                        uploadError.value = 'Authentication is required to upload images.';
×
NEW
21
                        return null;
×
NEW
22
                }
×
23

NEW
24
                uploadingImage.value = true;
×
NEW
25
                uploadError.value = '';
×
26

NEW
27
                try {
×
NEW
28
                        await kvAuth0.checkSession();
×
NEW
29
                        const token = kvAuth0.accessToken;
×
30

NEW
31
                        if (!file || !ALLOWED_TYPES.includes(file.type)) {
×
NEW
32
                                uploadError.value = 'Invalid file type. Please upload a PNG, JPEG, or GIF image.';
×
NEW
33
                                return null;
×
NEW
34
                        }
×
35

NEW
36
                        const formData = new FormData();
×
NEW
37
                        formData.append('image', file);
×
38

NEW
39
                        const headers = {
×
NEW
40
                                Authorization: token ? `Bearer ${token}` : '',
×
NEW
41
                        };
×
42

NEW
43
                        const fakeAuthInfo = kvAuth0.getFakeAuthCookieValue?.();
×
NEW
44
                        if (fakeAuthInfo?.userId) {
×
NEW
45
                                headers['x-fa-user-id'] = String(fakeAuthInfo.userId);
×
NEW
46
                        }
×
47

NEW
48
                        const appOrigin = appHost ? `https://${appHost}` : '';
×
NEW
49
                        const isViewingFromDifferentOrigin = typeof window !== 'undefined' && appOrigin
×
NEW
50
                                && window.location.origin !== appOrigin;
×
NEW
51
                        const uploadEndpoint = isViewingFromDifferentOrigin ? `${appOrigin}/img/upload` : '/img/upload';
×
NEW
52
                        const response = await fetch(uploadEndpoint, {
×
NEW
53
                                method: 'POST',
×
NEW
54
                                headers,
×
NEW
55
                                body: formData,
×
NEW
56
                        });
×
57

NEW
58
                        if (!response.ok) {
×
NEW
59
                                const errorText = await response.text();
×
NEW
60
                                throw new Error(errorText || `Upload failed (${response.status})`);
×
NEW
61
                        }
×
62

NEW
63
                        const result = await response.json();
×
64

NEW
65
                        if (!result?.id) {
×
NEW
66
                                uploadError.value = 'Failed to upload image.';
×
NEW
67
                                return null;
×
NEW
68
                        }
×
69

NEW
70
                        return result.id;
×
NEW
71
                } catch (error) {
×
NEW
72
                        uploadError.value = error instanceof Error ? error.message : 'Failed to upload image';
×
NEW
73
                        return null;
×
NEW
74
                } finally {
×
NEW
75
                        uploadingImage.value = false;
×
NEW
76
                }
×
NEW
77
        };
×
78

NEW
79
        return {
×
NEW
80
                uploadImage,
×
NEW
81
                uploadingImage,
×
NEW
82
                uploadError,
×
NEW
83
        };
×
NEW
84
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc