cloudcommerce 0.0.50 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/CONTRIBUTING.md +2 -2
- package/package.json +9 -9
- package/packages/api/lib/index.d.ts +40 -104
- package/packages/api/lib/types/applications.d.ts +10 -62
- package/packages/api/package.json +1 -1
- package/packages/api/src/types/applications.d.ts +10 -62
- package/packages/apps/_app.config.js +80 -0
- package/packages/apps/discounts/lib/discounts.config.d.ts +14 -0
- package/packages/apps/discounts/lib/discounts.config.js +19 -0
- package/packages/apps/discounts/lib/discounts.config.js.map +1 -0
- package/packages/apps/discounts/lib/discounts.d.ts +2 -0
- package/packages/apps/discounts/lib/discounts.js +7 -0
- package/packages/apps/discounts/lib/discounts.js.map +1 -0
- package/packages/apps/discounts/lib/index.d.ts +1 -3
- package/packages/apps/discounts/lib/index.js +1 -8
- package/packages/apps/discounts/lib/index.js.map +1 -1
- package/packages/apps/discounts/package.json +3 -2
- package/packages/apps/discounts/src/discounts.config.ts +25 -0
- package/packages/apps/discounts/src/discounts.ts +8 -0
- package/packages/apps/discounts/src/index.ts +1 -9
- package/packages/cli/config/firebase.json +16 -1
- package/packages/cli/lib/config-gcloud.js +94 -0
- package/packages/cli/lib/create-auth.js +7 -7
- package/packages/cli/lib/index.js +16 -3
- package/packages/cli/package.json +2 -2
- package/packages/cli/src/config-gcloud.ts +103 -0
- package/packages/cli/src/create-auth.ts +7 -7
- package/packages/cli/src/index.ts +17 -4
- package/packages/events/lib/firebase.js +0 -2
- package/packages/events/lib/firebase.js.map +1 -1
- package/packages/events/package.json +1 -1
- package/packages/events/src/firebase.ts +0 -2
- package/packages/firebase/lib/config.js +12 -8
- package/packages/firebase/lib/config.js.map +1 -1
- package/packages/firebase/lib/index.d.ts +0 -1
- package/packages/firebase/lib/index.js +0 -4
- package/packages/firebase/lib/index.js.map +1 -1
- package/packages/firebase/package.json +1 -1
- package/packages/firebase/src/config.ts +13 -8
- package/packages/firebase/src/index.ts +0 -4
- package/packages/modules/lib/firebase/call-app-module.js +1 -1
- package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
- package/packages/modules/lib/firebase/handle-module.js.map +1 -1
- package/packages/modules/lib/firebase.js +0 -2
- package/packages/modules/lib/firebase.js.map +1 -1
- package/packages/modules/package.json +2 -2
- package/packages/modules/src/firebase/call-app-module.ts +1 -1
- package/packages/modules/src/firebase/handle-module.ts +3 -3
- package/packages/modules/src/firebase.ts +0 -2
- package/packages/passport/lib/firebase/handle-passport.js +108 -0
- package/packages/passport/lib/firebase/handle-passport.js.map +1 -0
- package/packages/passport/lib/firebase/serve-passport-api.js +41 -0
- package/packages/passport/lib/firebase/serve-passport-api.js.map +1 -0
- package/packages/passport/lib/firebase.js +22 -5
- package/packages/passport/lib/firebase.js.map +1 -1
- package/packages/passport/package.json +1 -1
- package/packages/passport/src/firebase/handle-passport.ts +149 -0
- package/packages/passport/src/firebase/serve-passport-api.ts +62 -0
- package/packages/passport/src/firebase.ts +32 -7
- package/packages/ssr/package.json +1 -1
- package/packages/storefront/package.json +12 -2
- package/packages/types/index.ts +9 -0
- package/packages/types/package.json +1 -1
- package/packages/firebase/lib/handlers/auth-callback.d.ts +0 -3
- package/packages/firebase/lib/handlers/auth-callback.js +0 -45
- package/packages/firebase/lib/handlers/auth-callback.js.map +0 -1
- package/packages/firebase/src/handlers/auth-callback.ts +0 -49
- package/packages/passport/src/firebase/.gitkeep +0 -0
- package/pnpm-lock.yaml +0 -7887
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { Response } from 'firebase-functions';
|
|
2
|
+
import type { Customers } from '@cloudcommerce/types';
|
|
3
|
+
import type { Firestore } from 'firebase-admin/firestore';
|
|
4
|
+
// eslint-disable-next-line import/no-unresolved
|
|
5
|
+
import { Auth } from 'firebase-admin/auth';
|
|
6
|
+
import { logger } from 'firebase-functions';
|
|
7
|
+
import api from '@cloudcommerce/api';
|
|
8
|
+
|
|
9
|
+
const findCustomerByEmail = async (
|
|
10
|
+
email: string | undefined,
|
|
11
|
+
apiAuth: { authenticationId: string, apiKey: string },
|
|
12
|
+
) => {
|
|
13
|
+
try {
|
|
14
|
+
const { data } = await api.get(`customers?main_email=${email}`, apiAuth);
|
|
15
|
+
if (data.result.length) {
|
|
16
|
+
return data.result[0];
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
logger.error(e);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const checkFirebaseAuth = async (
|
|
26
|
+
auth: Auth,
|
|
27
|
+
authToken: string | undefined | string [],
|
|
28
|
+
) => {
|
|
29
|
+
if (authToken && !Array.isArray(authToken)) {
|
|
30
|
+
try {
|
|
31
|
+
const customer = await auth.verifyIdToken(authToken);
|
|
32
|
+
return customer;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const createCustomer = async (
|
|
42
|
+
customer: Customers,
|
|
43
|
+
apiAuth: { authenticationId: string, apiKey: string },
|
|
44
|
+
) => {
|
|
45
|
+
try {
|
|
46
|
+
const { data } = await api.post('customers', customer, apiAuth);
|
|
47
|
+
return data._id;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
logger.error(e);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const generateAccessToken = async (
|
|
55
|
+
firestore: Firestore,
|
|
56
|
+
customerId: string,
|
|
57
|
+
apiAuth: { authenticationId: string, apiKey: string },
|
|
58
|
+
): Promise<null | {
|
|
59
|
+
customer_id: string,
|
|
60
|
+
access_token: string,
|
|
61
|
+
expires: string,
|
|
62
|
+
}> => {
|
|
63
|
+
const docRef = firestore.doc(`customerTokens/${customerId}`);
|
|
64
|
+
const doc = await docRef.get();
|
|
65
|
+
const expires: string | undefined = doc.data()?.expires;
|
|
66
|
+
if (expires && new Date(expires).getTime() - Date.now() >= 2 * 60 * 1000) {
|
|
67
|
+
return doc.data() as { customer_id: string, access_token: string, expires: string };
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const { data } = await api({
|
|
71
|
+
endpoint: 'authenticate',
|
|
72
|
+
method: 'post',
|
|
73
|
+
body: {
|
|
74
|
+
_id: apiAuth.authenticationId,
|
|
75
|
+
api_key: apiAuth.apiKey,
|
|
76
|
+
customer_id: customerId,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const accessToken = {
|
|
80
|
+
access_token: data.access_token,
|
|
81
|
+
expires: data.expires,
|
|
82
|
+
customer_id: customerId,
|
|
83
|
+
};
|
|
84
|
+
docRef.set(accessToken).catch(logger.error);
|
|
85
|
+
return accessToken;
|
|
86
|
+
} catch (e) {
|
|
87
|
+
logger.error(e);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const getAuthCustomerApi = async (
|
|
93
|
+
firestore: Firestore,
|
|
94
|
+
apiAuth: { authenticationId: string, apiKey: string },
|
|
95
|
+
authtoken: string | string[] | undefined,
|
|
96
|
+
authFirebase: Auth,
|
|
97
|
+
) => {
|
|
98
|
+
const customerFirebaseAuth = await checkFirebaseAuth(authFirebase, authtoken);
|
|
99
|
+
if (customerFirebaseAuth !== null && customerFirebaseAuth.email) {
|
|
100
|
+
const customer = await findCustomerByEmail(
|
|
101
|
+
customerFirebaseAuth.email,
|
|
102
|
+
apiAuth,
|
|
103
|
+
);
|
|
104
|
+
if (customer !== null) {
|
|
105
|
+
return generateAccessToken(firestore, customer._id, apiAuth);
|
|
106
|
+
}
|
|
107
|
+
const newCustomer = {
|
|
108
|
+
display_name: customerFirebaseAuth.name || '',
|
|
109
|
+
main_email: customerFirebaseAuth.email,
|
|
110
|
+
emails: [{
|
|
111
|
+
address: customerFirebaseAuth.email,
|
|
112
|
+
verified: customerFirebaseAuth.email_verified,
|
|
113
|
+
}],
|
|
114
|
+
oauth_providers: [{
|
|
115
|
+
provider: customerFirebaseAuth.firebase.sign_in_provider,
|
|
116
|
+
user_id: customerFirebaseAuth.user_id,
|
|
117
|
+
}],
|
|
118
|
+
} as Customers;
|
|
119
|
+
const customerId = await createCustomer(newCustomer, apiAuth);
|
|
120
|
+
if (customerId) {
|
|
121
|
+
return generateAccessToken(firestore, customerId, apiAuth);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// TODO: Find customer by phone number, generate token if found, otherwise unauthorize
|
|
125
|
+
return null;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const sendError = (
|
|
129
|
+
res: Response,
|
|
130
|
+
msg?: string,
|
|
131
|
+
status = 400,
|
|
132
|
+
) => {
|
|
133
|
+
if (msg) {
|
|
134
|
+
res.status(status).json({
|
|
135
|
+
status,
|
|
136
|
+
error: msg,
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
res.status(500).json({
|
|
140
|
+
status: 500,
|
|
141
|
+
error: 'Internal server error',
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export {
|
|
147
|
+
sendError,
|
|
148
|
+
getAuthCustomerApi,
|
|
149
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Request, Response } from 'firebase-functions';
|
|
2
|
+
// eslint-disable-next-line import/no-unresolved
|
|
3
|
+
import type { Auth } from 'firebase-admin/auth';
|
|
4
|
+
// eslint-disable-next-line import/no-unresolved
|
|
5
|
+
import type { Firestore } from 'firebase-admin/firestore';
|
|
6
|
+
import { logger } from 'firebase-functions';
|
|
7
|
+
import {
|
|
8
|
+
sendError,
|
|
9
|
+
getAuthCustomerApi,
|
|
10
|
+
} from './handle-passport';
|
|
11
|
+
|
|
12
|
+
export default async (
|
|
13
|
+
req: Request,
|
|
14
|
+
res: Response,
|
|
15
|
+
apiAuth: { authenticationId: string, apiKey: string },
|
|
16
|
+
firestore: Firestore,
|
|
17
|
+
authFirebase: Auth,
|
|
18
|
+
storeId: number,
|
|
19
|
+
) => {
|
|
20
|
+
const { method } = req;
|
|
21
|
+
if (method !== 'POST') {
|
|
22
|
+
return res.sendStatus(405);
|
|
23
|
+
}
|
|
24
|
+
if (
|
|
25
|
+
method === 'POST'
|
|
26
|
+
&& (!req.body || typeof req.body !== 'object' || Array.isArray(req.body))
|
|
27
|
+
) {
|
|
28
|
+
return res.sendStatus(400);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let { url } = req;
|
|
32
|
+
if (url.endsWith('.json')) {
|
|
33
|
+
url = url.slice(0, -5);
|
|
34
|
+
}
|
|
35
|
+
const endpoint = url.split('/')[1];
|
|
36
|
+
// endpoint /token
|
|
37
|
+
if (endpoint === 'token' && method === 'POST') {
|
|
38
|
+
const { authtoken } = req.body;
|
|
39
|
+
if (!firestore) {
|
|
40
|
+
return sendError(res, 'Firestore not found', 500);
|
|
41
|
+
} if (storeId < 100) {
|
|
42
|
+
return sendError(res, 'Invalid store');
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const authCustomerApi = await getAuthCustomerApi(
|
|
46
|
+
firestore,
|
|
47
|
+
apiAuth,
|
|
48
|
+
authtoken,
|
|
49
|
+
authFirebase,
|
|
50
|
+
);
|
|
51
|
+
if (authCustomerApi !== null) {
|
|
52
|
+
return res.send(authCustomerApi);
|
|
53
|
+
}
|
|
54
|
+
return sendError(res, 'Invalid token, unauthorized', 401);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
logger.error(e);
|
|
57
|
+
return sendError(res);
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
return res.sendStatus(400);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
@@ -1,16 +1,41 @@
|
|
|
1
|
-
/* eslint-disable import/prefer-default-export */
|
|
2
|
-
|
|
3
1
|
import 'source-map-support/register.js';
|
|
4
2
|
// eslint-disable-next-line import/no-unresolved
|
|
5
3
|
import { initializeApp } from 'firebase-admin/app';
|
|
6
4
|
// eslint-disable-next-line import/no-unresolved
|
|
7
|
-
import {
|
|
5
|
+
import { getFirestore } from 'firebase-admin/firestore';
|
|
6
|
+
// eslint-disable-next-line import/no-unresolved
|
|
7
|
+
import { getAuth } from 'firebase-admin/auth';
|
|
8
|
+
// eslint-disable-next-line import/no-unresolved
|
|
9
|
+
import { HttpsOptions, onRequest } from 'firebase-functions/v2/https';
|
|
8
10
|
import config from '@cloudcommerce/firebase/lib/config';
|
|
11
|
+
import getEnv from '@cloudcommerce/firebase/lib/env';
|
|
12
|
+
import servePassportApi from './firebase/serve-passport-api';
|
|
13
|
+
|
|
14
|
+
// References:
|
|
15
|
+
// https:// firebase.google.com/docs/auth/admin/manage-cookies
|
|
16
|
+
// https://itnext.io/how-to-use-firebase-auth-with-a-custom-node-backend-99a106376c8a
|
|
17
|
+
// https://www.geeksforgeeks.org/firebase-sign-in-with-google-authentication-in-node-js-using-firebase-ui-and-cookie-sessions/
|
|
18
|
+
// https://firebase.google.com/docs/reference/rest/auth
|
|
9
19
|
|
|
10
20
|
initializeApp();
|
|
11
|
-
const
|
|
21
|
+
const authFirebase = getAuth();
|
|
22
|
+
const firestore = getFirestore();
|
|
23
|
+
|
|
24
|
+
const options = {
|
|
25
|
+
...config.get().httpsFunctionOptions,
|
|
26
|
+
memory: '128MiB',
|
|
27
|
+
} as HttpsOptions;
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
30
|
+
export const passport = onRequest(options, (req, res) => {
|
|
31
|
+
const { apiAuth } = getEnv();
|
|
32
|
+
const { storeId } = config.get();
|
|
33
|
+
servePassportApi(
|
|
34
|
+
req,
|
|
35
|
+
res,
|
|
36
|
+
apiAuth,
|
|
37
|
+
firestore,
|
|
38
|
+
authFirebase,
|
|
39
|
+
storeId,
|
|
40
|
+
);
|
|
16
41
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/storefront",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.53",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce storefront with Astro",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -19,7 +19,17 @@
|
|
|
19
19
|
"build": "echo '@ecomplus/storefront'"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
+
"@astrojs/mdx": "^0.9.0",
|
|
23
|
+
"@astrojs/node": "^1.0.0",
|
|
24
|
+
"@astrojs/partytown": "^1.0.0",
|
|
25
|
+
"@astrojs/prefetch": "^0.0.7",
|
|
26
|
+
"@astrojs/sitemap": "^1.0.0",
|
|
27
|
+
"@astrojs/tailwind": "^1.0.0",
|
|
28
|
+
"@astrojs/vue": "^1.0.0",
|
|
22
29
|
"@cloudcommerce/api": "workspace:*",
|
|
23
|
-
"
|
|
30
|
+
"@picocss/pico": "^1.5.3",
|
|
31
|
+
"astro": "^1.0.5",
|
|
32
|
+
"rollup": "^2.78.0",
|
|
33
|
+
"vue": "^3.2.37"
|
|
24
34
|
}
|
|
25
35
|
}
|
package/packages/types/index.ts
CHANGED
|
@@ -42,6 +42,14 @@ type AppModuleName = 'apply_discount'
|
|
|
42
42
|
| 'list_payments'
|
|
43
43
|
| 'create_transaction';
|
|
44
44
|
|
|
45
|
+
type AppModuleBody = {
|
|
46
|
+
module: AppModuleName,
|
|
47
|
+
params: {
|
|
48
|
+
[key: string]: any,
|
|
49
|
+
},
|
|
50
|
+
application: Applications,
|
|
51
|
+
};
|
|
52
|
+
|
|
45
53
|
export type {
|
|
46
54
|
Products,
|
|
47
55
|
Categories,
|
|
@@ -60,6 +68,7 @@ export type {
|
|
|
60
68
|
EventsResult,
|
|
61
69
|
AppEventsTopic,
|
|
62
70
|
AppModuleName,
|
|
71
|
+
AppModuleBody,
|
|
63
72
|
ApplyDiscountParams,
|
|
64
73
|
ApplyDiscountResponse,
|
|
65
74
|
CalculateShippingParams,
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-unresolved
|
|
2
|
-
import { getFirestore } from 'firebase-admin/firestore';
|
|
3
|
-
import api from '@cloudcommerce/api';
|
|
4
|
-
import config from '../config.js';
|
|
5
|
-
|
|
6
|
-
export default async (req, res) => {
|
|
7
|
-
const { storeId, apps } = config.get();
|
|
8
|
-
const { body } = req;
|
|
9
|
-
if (Number(req.get('X-Store-ID')) === storeId
|
|
10
|
-
&& body && body.store_id === storeId) {
|
|
11
|
-
const { application, authentication } = body;
|
|
12
|
-
if (application && authentication) {
|
|
13
|
-
const matchApp = Object.keys(apps).find((slug) => {
|
|
14
|
-
return apps[slug].appId === application.app_id;
|
|
15
|
-
});
|
|
16
|
-
if (matchApp) {
|
|
17
|
-
const authenticationId = authentication.authentication_id;
|
|
18
|
-
const firestoreDoc = getFirestore().doc(`installedApps/${authenticationId}`);
|
|
19
|
-
const installedApp = await firestoreDoc.get();
|
|
20
|
-
if (installedApp.exists) {
|
|
21
|
-
res.sendStatus(200);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
const appDataEndpoint = `applications/${application._id}/hidden_data`;
|
|
25
|
-
try {
|
|
26
|
-
await api.patch(appDataEndpoint, {
|
|
27
|
-
__installedAt: new Date().toISOString(),
|
|
28
|
-
}, {
|
|
29
|
-
authenticationId: authentication._id,
|
|
30
|
-
apiKey: authentication.api_key,
|
|
31
|
-
});
|
|
32
|
-
} catch (e) {
|
|
33
|
-
res.sendStatus(403);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
// Received app authentication is valid
|
|
37
|
-
await firestoreDoc.set({ application, authentication });
|
|
38
|
-
res.sendStatus(201);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
res.sendStatus(400);
|
|
44
|
-
};
|
|
45
|
-
// # sourceMappingURL=auth-callback.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-callback.js","sourceRoot":"","sources":["../../src/handlers/auth-callback.ts"],"names":[],"mappings":"AACA,gDAAgD;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,GAAoB,MAAM,oBAAoB,CAAC;AACtD,OAAO,MAAM,MAAM,WAAW,CAAC;AAE/B,eAAe,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IACvC,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;IACrB,IACE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,KAAK,OAAO;WACtC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EACpC;QACA,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;QAC7C,IAAI,WAAW,IAAI,cAAc,EAAE;YACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,MAAM,CAAC;YACjD,CAAC,CAAC,CAAC;YACH,IAAI,QAAQ,EAAE;gBACZ,MAAM,gBAAgB,GAAG,cAAc,CAAC,iBAAiB,CAAC;gBAC1D,MAAM,YAAY,GAAG,YAAY,EAAE,CAAC,GAAG,CAAC,iBAAiB,gBAAgB,EAAE,CAAC,CAAC;gBAC7E,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC;gBAC9C,IAAI,YAAY,CAAC,MAAM,EAAE;oBACvB,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBACpB,OAAO;iBACR;gBAED,MAAM,eAAe,GAAgB,gBAAgB,WAAW,CAAC,GAAG,cAAc,CAAC;gBACnF,IAAI;oBACF,MAAM,GAAG,CAAC,KAAK,CAAC,eAAe,EAAE;wBAC/B,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACxC,EAAE;wBACD,gBAAgB,EAAE,cAAc,CAAC,GAAG;wBACpC,MAAM,EAAE,cAAc,CAAC,OAAO;qBAC/B,CAAC,CAAC;iBACJ;gBAAC,OAAO,CAAC,EAAE;oBACV,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBACpB,OAAO;iBACR;gBAED,uCAAuC;gBACvC,MAAM,YAAY,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC;gBACxD,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBACpB,OAAO;aACR;SACF;KACF;IACD,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC,CAAC"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { Request, Response } from 'firebase-functions';
|
|
2
|
-
// eslint-disable-next-line import/no-unresolved
|
|
3
|
-
import { getFirestore } from 'firebase-admin/firestore';
|
|
4
|
-
import api, { ApiEndpoint } from '@cloudcommerce/api';
|
|
5
|
-
import config from '../config';
|
|
6
|
-
|
|
7
|
-
export default async (req: Request, res: Response) => {
|
|
8
|
-
const { storeId, apps } = config.get();
|
|
9
|
-
const { body } = req;
|
|
10
|
-
if (
|
|
11
|
-
Number(req.get('X-Store-ID')) === storeId
|
|
12
|
-
&& body && body.store_id === storeId
|
|
13
|
-
) {
|
|
14
|
-
const { application, authentication } = body;
|
|
15
|
-
if (application && authentication) {
|
|
16
|
-
const matchApp = Object.keys(apps).find((slug) => {
|
|
17
|
-
return apps[slug].appId === application.app_id;
|
|
18
|
-
});
|
|
19
|
-
if (matchApp) {
|
|
20
|
-
const authenticationId = authentication.authentication_id;
|
|
21
|
-
const firestoreDoc = getFirestore().doc(`installedApps/${authenticationId}`);
|
|
22
|
-
const installedApp = await firestoreDoc.get();
|
|
23
|
-
if (installedApp.exists) {
|
|
24
|
-
res.sendStatus(200);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const appDataEndpoint: ApiEndpoint = `applications/${application._id}/hidden_data`;
|
|
29
|
-
try {
|
|
30
|
-
await api.patch(appDataEndpoint, {
|
|
31
|
-
__installedAt: new Date().toISOString(),
|
|
32
|
-
}, {
|
|
33
|
-
authenticationId: authentication._id,
|
|
34
|
-
apiKey: authentication.api_key,
|
|
35
|
-
});
|
|
36
|
-
} catch (e) {
|
|
37
|
-
res.sendStatus(403);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Received app authentication is valid
|
|
42
|
-
await firestoreDoc.set({ application, authentication });
|
|
43
|
-
res.sendStatus(201);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
res.sendStatus(400);
|
|
49
|
-
};
|
|
File without changes
|