@drawbridge/drawbridge-utils 0.0.19 → 0.0.21
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/dist/shopify.cjs +67 -59
- package/dist/shopify.d.cts +77 -67
- package/dist/shopify.d.ts +77 -67
- package/dist/shopify.js +64 -58
- package/package.json +1 -1
package/dist/shopify.cjs
CHANGED
|
@@ -30,7 +30,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var shopify_exports = {};
|
|
31
31
|
__export(shopify_exports, {
|
|
32
32
|
getAdminToken: () => getAdminToken,
|
|
33
|
-
|
|
33
|
+
ping: () => ping,
|
|
34
|
+
refreshAdminToken: () => refreshAdminToken,
|
|
35
|
+
resolveConnectionSettings: () => resolveConnectionSettings
|
|
34
36
|
});
|
|
35
37
|
module.exports = __toCommonJS(shopify_exports);
|
|
36
38
|
|
|
@@ -66,6 +68,8 @@ var decrypt = (value) => {
|
|
|
66
68
|
|
|
67
69
|
// shopify.js
|
|
68
70
|
var SHOPIFY_ADMIN_API_VERSION = "2025-01";
|
|
71
|
+
var REFRESH_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
72
|
+
var ACCESS_TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
69
73
|
var shopifyOAuthFetch = async (url, body) => {
|
|
70
74
|
const response = await fetch(url, {
|
|
71
75
|
method: "POST",
|
|
@@ -82,7 +86,7 @@ var shopifyOAuthFetch = async (url, body) => {
|
|
|
82
86
|
}
|
|
83
87
|
return response.json();
|
|
84
88
|
};
|
|
85
|
-
var
|
|
89
|
+
var ping = async ({ adminAccessToken, domain }) => {
|
|
86
90
|
const response = await fetch(
|
|
87
91
|
`https://${domain}/admin/api/${SHOPIFY_ADMIN_API_VERSION}/shop.json`,
|
|
88
92
|
{
|
|
@@ -98,9 +102,37 @@ var pingShop = async ({ adminAccessToken, domain }) => {
|
|
|
98
102
|
throw error;
|
|
99
103
|
}
|
|
100
104
|
};
|
|
105
|
+
var resolveConnectionSettings = async ({ connection, controller }) => {
|
|
106
|
+
const connectionSettings = (connection == null ? void 0 : connection.settings) ? decrypt(connection.settings) : {};
|
|
107
|
+
if (!(connection == null ? void 0 : connection.credential)) {
|
|
108
|
+
return connectionSettings;
|
|
109
|
+
}
|
|
110
|
+
const credential = await controller.get({
|
|
111
|
+
collection: "credential",
|
|
112
|
+
query: {
|
|
113
|
+
id: connection.credential
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
const credentialSettings = (credential == null ? void 0 : credential.settings) ? decrypt(credential.settings) : {};
|
|
117
|
+
return {
|
|
118
|
+
...credentialSettings,
|
|
119
|
+
...connectionSettings
|
|
120
|
+
};
|
|
121
|
+
};
|
|
101
122
|
var refreshAdminToken = async ({ connection, controller }) => {
|
|
102
|
-
const
|
|
103
|
-
|
|
123
|
+
const credential = await controller.get({
|
|
124
|
+
collection: "credential",
|
|
125
|
+
query: {
|
|
126
|
+
id: connection.credential
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
if (!credential) {
|
|
130
|
+
throw new Error("refreshAdminToken: credential not found for connection " + connection.id);
|
|
131
|
+
}
|
|
132
|
+
;
|
|
133
|
+
const settings = decrypt(credential.settings);
|
|
134
|
+
const { identifier: domain } = credential;
|
|
135
|
+
const { refreshToken } = settings;
|
|
104
136
|
const data = await shopifyOAuthFetch(
|
|
105
137
|
`https://${domain}/admin/oauth/access_token`,
|
|
106
138
|
{
|
|
@@ -114,73 +146,49 @@ var refreshAdminToken = async ({ connection, controller }) => {
|
|
|
114
146
|
const newRefreshToken = data.refresh_token;
|
|
115
147
|
const expiresIn = data.expires_in;
|
|
116
148
|
const tokenExpiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1e3) : null;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
collection: "connection",
|
|
131
|
-
data: {
|
|
132
|
-
$set: {
|
|
133
|
-
settings: encrypt({
|
|
134
|
-
...settings,
|
|
135
|
-
adminAccessToken,
|
|
136
|
-
refreshToken: newRefreshToken,
|
|
137
|
-
tokenExpiresAt
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
options,
|
|
142
|
-
query: {
|
|
143
|
-
id: connection.id
|
|
149
|
+
const refreshTokenExpiresAt = new Date(Date.now() + REFRESH_TOKEN_LIFETIME_MS);
|
|
150
|
+
await ping({ adminAccessToken, domain });
|
|
151
|
+
await controller.update({
|
|
152
|
+
collection: "credential",
|
|
153
|
+
data: {
|
|
154
|
+
$set: {
|
|
155
|
+
settings: encrypt({
|
|
156
|
+
...settings,
|
|
157
|
+
adminAccessToken,
|
|
158
|
+
refreshToken: newRefreshToken,
|
|
159
|
+
refreshTokenExpiresAt,
|
|
160
|
+
tokenExpiresAt
|
|
161
|
+
})
|
|
144
162
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
collection: "action",
|
|
149
|
-
data: {
|
|
150
|
-
completedAt: /* @__PURE__ */ new Date(),
|
|
151
|
-
error: null,
|
|
152
|
-
errorStatus: null,
|
|
153
|
-
organization: connection.organization,
|
|
154
|
-
request: null,
|
|
155
|
-
response: null,
|
|
156
|
-
slug: "action.shopify.token.refresh",
|
|
157
|
-
status: "succeeded",
|
|
158
|
-
trigger: {
|
|
159
|
-
data: {
|
|
160
|
-
connection: connection.id
|
|
161
|
-
},
|
|
162
|
-
event: "shopify.token"
|
|
163
|
-
},
|
|
164
|
-
usage: null,
|
|
165
|
-
workflow: tokenWorkflow.id
|
|
166
|
-
},
|
|
167
|
-
options
|
|
168
|
-
});
|
|
163
|
+
},
|
|
164
|
+
query: {
|
|
165
|
+
id: credential.id
|
|
169
166
|
}
|
|
170
|
-
;
|
|
171
167
|
});
|
|
172
168
|
return adminAccessToken;
|
|
173
169
|
};
|
|
174
170
|
var getAdminToken = async ({ connection, controller }) => {
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
if (!(connection == null ? void 0 : connection.credential)) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
;
|
|
175
|
+
const settings = await resolveConnectionSettings({ connection, controller });
|
|
176
|
+
const { adminAccessToken, refreshToken, tokenExpiresAt } = settings;
|
|
177
|
+
if (!refreshToken) {
|
|
178
|
+
return adminAccessToken;
|
|
179
|
+
}
|
|
180
|
+
;
|
|
181
|
+
const needsRefresh = !tokenExpiresAt || new Date(tokenExpiresAt) < new Date(Date.now() + ACCESS_TOKEN_REFRESH_BUFFER_MS);
|
|
177
182
|
if (needsRefresh) {
|
|
178
183
|
return refreshAdminToken({ connection, controller });
|
|
179
184
|
}
|
|
185
|
+
;
|
|
180
186
|
return adminAccessToken;
|
|
181
187
|
};
|
|
182
188
|
// Annotate the CommonJS export names for ESM import in node:
|
|
183
189
|
0 && (module.exports = {
|
|
184
190
|
getAdminToken,
|
|
185
|
-
|
|
191
|
+
ping,
|
|
192
|
+
refreshAdminToken,
|
|
193
|
+
resolveConnectionSettings
|
|
186
194
|
});
|
package/dist/shopify.d.cts
CHANGED
|
@@ -2,6 +2,8 @@ import { decrypt, encrypt } from './encrypt.cjs';
|
|
|
2
2
|
import 'crypto';
|
|
3
3
|
|
|
4
4
|
const SHOPIFY_ADMIN_API_VERSION = '2025-01';
|
|
5
|
+
const REFRESH_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1000;
|
|
6
|
+
const ACCESS_TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
5
7
|
|
|
6
8
|
const shopifyOAuthFetch = async ( url, body ) => {
|
|
7
9
|
|
|
@@ -28,7 +30,7 @@ const shopifyOAuthFetch = async ( url, body ) => {
|
|
|
28
30
|
|
|
29
31
|
};
|
|
30
32
|
|
|
31
|
-
const
|
|
33
|
+
const ping = async ({ adminAccessToken, domain }) => {
|
|
32
34
|
|
|
33
35
|
const response = await fetch(
|
|
34
36
|
`https://${ domain }/admin/api/${ SHOPIFY_ADMIN_API_VERSION }/shop.json`,
|
|
@@ -52,10 +54,49 @@ const pingShop = async ({ adminAccessToken, domain }) => {
|
|
|
52
54
|
|
|
53
55
|
};
|
|
54
56
|
|
|
57
|
+
const resolveConnectionSettings = async ({ connection, controller }) => {
|
|
58
|
+
|
|
59
|
+
const connectionSettings = connection?.settings ? decrypt( connection.settings ) : {};
|
|
60
|
+
|
|
61
|
+
if( ! connection?.credential ){
|
|
62
|
+
|
|
63
|
+
return connectionSettings;
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const credential = await controller.get({
|
|
68
|
+
collection : 'credential',
|
|
69
|
+
query : {
|
|
70
|
+
id : connection.credential
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const credentialSettings = credential?.settings ? decrypt( credential.settings ) : {};
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
...credentialSettings,
|
|
78
|
+
...connectionSettings
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
};
|
|
82
|
+
|
|
55
83
|
const refreshAdminToken = async ({ connection, controller }) => {
|
|
56
84
|
|
|
57
|
-
const
|
|
58
|
-
|
|
85
|
+
const credential = await controller.get({
|
|
86
|
+
collection : 'credential',
|
|
87
|
+
query : {
|
|
88
|
+
id : connection.credential
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if( ! credential ){
|
|
93
|
+
|
|
94
|
+
throw new Error( 'refreshAdminToken: credential not found for connection ' + connection.id );
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
const settings = decrypt( credential.settings );
|
|
98
|
+
const { identifier : domain } = credential;
|
|
99
|
+
const { refreshToken } = settings;
|
|
59
100
|
|
|
60
101
|
const data = await shopifyOAuthFetch(
|
|
61
102
|
`https://${ domain }/admin/oauth/access_token`,
|
|
@@ -71,88 +112,57 @@ const refreshAdminToken = async ({ connection, controller }) => {
|
|
|
71
112
|
const newRefreshToken = data.refresh_token;
|
|
72
113
|
const expiresIn = data.expires_in;
|
|
73
114
|
const tokenExpiresAt = expiresIn ? new Date( Date.now() + ( expiresIn * 1000 ) ) : null;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
115
|
+
const refreshTokenExpiresAt = new Date( Date.now() + REFRESH_TOKEN_LIFETIME_MS );
|
|
116
|
+
|
|
117
|
+
await ping({ adminAccessToken, domain });
|
|
118
|
+
|
|
119
|
+
await controller.update({
|
|
120
|
+
collection : 'credential',
|
|
121
|
+
data : {
|
|
122
|
+
$set : {
|
|
123
|
+
settings : encrypt({
|
|
124
|
+
...settings,
|
|
125
|
+
adminAccessToken,
|
|
126
|
+
refreshToken : newRefreshToken,
|
|
127
|
+
refreshTokenExpiresAt,
|
|
128
|
+
tokenExpiresAt
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
},
|
|
79
132
|
query : {
|
|
80
|
-
|
|
81
|
-
organization : connection.organization,
|
|
82
|
-
system : true,
|
|
83
|
-
title : 'Shopify Token Activity'
|
|
133
|
+
id : credential.id
|
|
84
134
|
}
|
|
85
135
|
});
|
|
86
136
|
|
|
87
|
-
await controller.transaction( async ( session ) => {
|
|
88
|
-
|
|
89
|
-
const options = { session };
|
|
90
|
-
|
|
91
|
-
await controller.update({
|
|
92
|
-
collection : 'connection',
|
|
93
|
-
data : {
|
|
94
|
-
$set : {
|
|
95
|
-
settings : encrypt({
|
|
96
|
-
...settings,
|
|
97
|
-
adminAccessToken,
|
|
98
|
-
refreshToken : newRefreshToken,
|
|
99
|
-
tokenExpiresAt
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
options,
|
|
104
|
-
query : {
|
|
105
|
-
id : connection.id
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
if( tokenWorkflow ){
|
|
110
|
-
|
|
111
|
-
await controller.create({
|
|
112
|
-
collection : 'action',
|
|
113
|
-
data : {
|
|
114
|
-
completedAt : new Date(),
|
|
115
|
-
error : null,
|
|
116
|
-
errorStatus : null,
|
|
117
|
-
organization : connection.organization,
|
|
118
|
-
request : null,
|
|
119
|
-
response : null,
|
|
120
|
-
slug : 'action.shopify.token.refresh',
|
|
121
|
-
status : 'succeeded',
|
|
122
|
-
trigger : {
|
|
123
|
-
data : {
|
|
124
|
-
connection : connection.id
|
|
125
|
-
},
|
|
126
|
-
event : 'shopify.token'
|
|
127
|
-
},
|
|
128
|
-
usage : null,
|
|
129
|
-
workflow : tokenWorkflow.id
|
|
130
|
-
},
|
|
131
|
-
options
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
} );
|
|
136
|
-
|
|
137
137
|
return adminAccessToken;
|
|
138
138
|
|
|
139
139
|
};
|
|
140
140
|
|
|
141
141
|
const getAdminToken = async ({ connection, controller }) => {
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
if( ! connection?.credential ){
|
|
144
|
+
|
|
145
|
+
return null;
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
const settings = await resolveConnectionSettings({ connection, controller });
|
|
149
|
+
const { adminAccessToken, refreshToken, tokenExpiresAt } = settings;
|
|
144
150
|
|
|
145
|
-
|
|
146
|
-
|
|
151
|
+
if( ! refreshToken ){
|
|
152
|
+
|
|
153
|
+
return adminAccessToken;
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
const needsRefresh = ! tokenExpiresAt ||
|
|
157
|
+
new Date( tokenExpiresAt ) < new Date( Date.now() + ACCESS_TOKEN_REFRESH_BUFFER_MS );
|
|
147
158
|
|
|
148
159
|
if( needsRefresh ){
|
|
149
160
|
|
|
150
161
|
return refreshAdminToken({ connection, controller });
|
|
151
162
|
|
|
152
163
|
}
|
|
153
|
-
|
|
154
164
|
return adminAccessToken;
|
|
155
165
|
|
|
156
166
|
};
|
|
157
167
|
|
|
158
|
-
export { getAdminToken, refreshAdminToken };
|
|
168
|
+
export { getAdminToken, ping, refreshAdminToken, resolveConnectionSettings };
|
package/dist/shopify.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { decrypt, encrypt } from './encrypt.js';
|
|
|
2
2
|
import 'crypto';
|
|
3
3
|
|
|
4
4
|
const SHOPIFY_ADMIN_API_VERSION = '2025-01';
|
|
5
|
+
const REFRESH_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1000;
|
|
6
|
+
const ACCESS_TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
5
7
|
|
|
6
8
|
const shopifyOAuthFetch = async ( url, body ) => {
|
|
7
9
|
|
|
@@ -28,7 +30,7 @@ const shopifyOAuthFetch = async ( url, body ) => {
|
|
|
28
30
|
|
|
29
31
|
};
|
|
30
32
|
|
|
31
|
-
const
|
|
33
|
+
const ping = async ({ adminAccessToken, domain }) => {
|
|
32
34
|
|
|
33
35
|
const response = await fetch(
|
|
34
36
|
`https://${ domain }/admin/api/${ SHOPIFY_ADMIN_API_VERSION }/shop.json`,
|
|
@@ -52,10 +54,49 @@ const pingShop = async ({ adminAccessToken, domain }) => {
|
|
|
52
54
|
|
|
53
55
|
};
|
|
54
56
|
|
|
57
|
+
const resolveConnectionSettings = async ({ connection, controller }) => {
|
|
58
|
+
|
|
59
|
+
const connectionSettings = connection?.settings ? decrypt( connection.settings ) : {};
|
|
60
|
+
|
|
61
|
+
if( ! connection?.credential ){
|
|
62
|
+
|
|
63
|
+
return connectionSettings;
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const credential = await controller.get({
|
|
68
|
+
collection : 'credential',
|
|
69
|
+
query : {
|
|
70
|
+
id : connection.credential
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const credentialSettings = credential?.settings ? decrypt( credential.settings ) : {};
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
...credentialSettings,
|
|
78
|
+
...connectionSettings
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
};
|
|
82
|
+
|
|
55
83
|
const refreshAdminToken = async ({ connection, controller }) => {
|
|
56
84
|
|
|
57
|
-
const
|
|
58
|
-
|
|
85
|
+
const credential = await controller.get({
|
|
86
|
+
collection : 'credential',
|
|
87
|
+
query : {
|
|
88
|
+
id : connection.credential
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if( ! credential ){
|
|
93
|
+
|
|
94
|
+
throw new Error( 'refreshAdminToken: credential not found for connection ' + connection.id );
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
const settings = decrypt( credential.settings );
|
|
98
|
+
const { identifier : domain } = credential;
|
|
99
|
+
const { refreshToken } = settings;
|
|
59
100
|
|
|
60
101
|
const data = await shopifyOAuthFetch(
|
|
61
102
|
`https://${ domain }/admin/oauth/access_token`,
|
|
@@ -71,88 +112,57 @@ const refreshAdminToken = async ({ connection, controller }) => {
|
|
|
71
112
|
const newRefreshToken = data.refresh_token;
|
|
72
113
|
const expiresIn = data.expires_in;
|
|
73
114
|
const tokenExpiresAt = expiresIn ? new Date( Date.now() + ( expiresIn * 1000 ) ) : null;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
115
|
+
const refreshTokenExpiresAt = new Date( Date.now() + REFRESH_TOKEN_LIFETIME_MS );
|
|
116
|
+
|
|
117
|
+
await ping({ adminAccessToken, domain });
|
|
118
|
+
|
|
119
|
+
await controller.update({
|
|
120
|
+
collection : 'credential',
|
|
121
|
+
data : {
|
|
122
|
+
$set : {
|
|
123
|
+
settings : encrypt({
|
|
124
|
+
...settings,
|
|
125
|
+
adminAccessToken,
|
|
126
|
+
refreshToken : newRefreshToken,
|
|
127
|
+
refreshTokenExpiresAt,
|
|
128
|
+
tokenExpiresAt
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
},
|
|
79
132
|
query : {
|
|
80
|
-
|
|
81
|
-
organization : connection.organization,
|
|
82
|
-
system : true,
|
|
83
|
-
title : 'Shopify Token Activity'
|
|
133
|
+
id : credential.id
|
|
84
134
|
}
|
|
85
135
|
});
|
|
86
136
|
|
|
87
|
-
await controller.transaction( async ( session ) => {
|
|
88
|
-
|
|
89
|
-
const options = { session };
|
|
90
|
-
|
|
91
|
-
await controller.update({
|
|
92
|
-
collection : 'connection',
|
|
93
|
-
data : {
|
|
94
|
-
$set : {
|
|
95
|
-
settings : encrypt({
|
|
96
|
-
...settings,
|
|
97
|
-
adminAccessToken,
|
|
98
|
-
refreshToken : newRefreshToken,
|
|
99
|
-
tokenExpiresAt
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
options,
|
|
104
|
-
query : {
|
|
105
|
-
id : connection.id
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
if( tokenWorkflow ){
|
|
110
|
-
|
|
111
|
-
await controller.create({
|
|
112
|
-
collection : 'action',
|
|
113
|
-
data : {
|
|
114
|
-
completedAt : new Date(),
|
|
115
|
-
error : null,
|
|
116
|
-
errorStatus : null,
|
|
117
|
-
organization : connection.organization,
|
|
118
|
-
request : null,
|
|
119
|
-
response : null,
|
|
120
|
-
slug : 'action.shopify.token.refresh',
|
|
121
|
-
status : 'succeeded',
|
|
122
|
-
trigger : {
|
|
123
|
-
data : {
|
|
124
|
-
connection : connection.id
|
|
125
|
-
},
|
|
126
|
-
event : 'shopify.token'
|
|
127
|
-
},
|
|
128
|
-
usage : null,
|
|
129
|
-
workflow : tokenWorkflow.id
|
|
130
|
-
},
|
|
131
|
-
options
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
} );
|
|
136
|
-
|
|
137
137
|
return adminAccessToken;
|
|
138
138
|
|
|
139
139
|
};
|
|
140
140
|
|
|
141
141
|
const getAdminToken = async ({ connection, controller }) => {
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
if( ! connection?.credential ){
|
|
144
|
+
|
|
145
|
+
return null;
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
const settings = await resolveConnectionSettings({ connection, controller });
|
|
149
|
+
const { adminAccessToken, refreshToken, tokenExpiresAt } = settings;
|
|
144
150
|
|
|
145
|
-
|
|
146
|
-
|
|
151
|
+
if( ! refreshToken ){
|
|
152
|
+
|
|
153
|
+
return adminAccessToken;
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
const needsRefresh = ! tokenExpiresAt ||
|
|
157
|
+
new Date( tokenExpiresAt ) < new Date( Date.now() + ACCESS_TOKEN_REFRESH_BUFFER_MS );
|
|
147
158
|
|
|
148
159
|
if( needsRefresh ){
|
|
149
160
|
|
|
150
161
|
return refreshAdminToken({ connection, controller });
|
|
151
162
|
|
|
152
163
|
}
|
|
153
|
-
|
|
154
164
|
return adminAccessToken;
|
|
155
165
|
|
|
156
166
|
};
|
|
157
167
|
|
|
158
|
-
export { getAdminToken, refreshAdminToken };
|
|
168
|
+
export { getAdminToken, ping, refreshAdminToken, resolveConnectionSettings };
|
package/dist/shopify.js
CHANGED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// shopify.js
|
|
7
7
|
var SHOPIFY_ADMIN_API_VERSION = "2025-01";
|
|
8
|
+
var REFRESH_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
9
|
+
var ACCESS_TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
8
10
|
var shopifyOAuthFetch = async (url, body) => {
|
|
9
11
|
const response = await fetch(url, {
|
|
10
12
|
method: "POST",
|
|
@@ -21,7 +23,7 @@ var shopifyOAuthFetch = async (url, body) => {
|
|
|
21
23
|
}
|
|
22
24
|
return response.json();
|
|
23
25
|
};
|
|
24
|
-
var
|
|
26
|
+
var ping = async ({ adminAccessToken, domain }) => {
|
|
25
27
|
const response = await fetch(
|
|
26
28
|
`https://${domain}/admin/api/${SHOPIFY_ADMIN_API_VERSION}/shop.json`,
|
|
27
29
|
{
|
|
@@ -37,9 +39,37 @@ var pingShop = async ({ adminAccessToken, domain }) => {
|
|
|
37
39
|
throw error;
|
|
38
40
|
}
|
|
39
41
|
};
|
|
42
|
+
var resolveConnectionSettings = async ({ connection, controller }) => {
|
|
43
|
+
const connectionSettings = (connection == null ? void 0 : connection.settings) ? decrypt(connection.settings) : {};
|
|
44
|
+
if (!(connection == null ? void 0 : connection.credential)) {
|
|
45
|
+
return connectionSettings;
|
|
46
|
+
}
|
|
47
|
+
const credential = await controller.get({
|
|
48
|
+
collection: "credential",
|
|
49
|
+
query: {
|
|
50
|
+
id: connection.credential
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const credentialSettings = (credential == null ? void 0 : credential.settings) ? decrypt(credential.settings) : {};
|
|
54
|
+
return {
|
|
55
|
+
...credentialSettings,
|
|
56
|
+
...connectionSettings
|
|
57
|
+
};
|
|
58
|
+
};
|
|
40
59
|
var refreshAdminToken = async ({ connection, controller }) => {
|
|
41
|
-
const
|
|
42
|
-
|
|
60
|
+
const credential = await controller.get({
|
|
61
|
+
collection: "credential",
|
|
62
|
+
query: {
|
|
63
|
+
id: connection.credential
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
if (!credential) {
|
|
67
|
+
throw new Error("refreshAdminToken: credential not found for connection " + connection.id);
|
|
68
|
+
}
|
|
69
|
+
;
|
|
70
|
+
const settings = decrypt(credential.settings);
|
|
71
|
+
const { identifier: domain } = credential;
|
|
72
|
+
const { refreshToken } = settings;
|
|
43
73
|
const data = await shopifyOAuthFetch(
|
|
44
74
|
`https://${domain}/admin/oauth/access_token`,
|
|
45
75
|
{
|
|
@@ -53,72 +83,48 @@ var refreshAdminToken = async ({ connection, controller }) => {
|
|
|
53
83
|
const newRefreshToken = data.refresh_token;
|
|
54
84
|
const expiresIn = data.expires_in;
|
|
55
85
|
const tokenExpiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1e3) : null;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
collection: "connection",
|
|
70
|
-
data: {
|
|
71
|
-
$set: {
|
|
72
|
-
settings: encrypt({
|
|
73
|
-
...settings,
|
|
74
|
-
adminAccessToken,
|
|
75
|
-
refreshToken: newRefreshToken,
|
|
76
|
-
tokenExpiresAt
|
|
77
|
-
})
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
options,
|
|
81
|
-
query: {
|
|
82
|
-
id: connection.id
|
|
86
|
+
const refreshTokenExpiresAt = new Date(Date.now() + REFRESH_TOKEN_LIFETIME_MS);
|
|
87
|
+
await ping({ adminAccessToken, domain });
|
|
88
|
+
await controller.update({
|
|
89
|
+
collection: "credential",
|
|
90
|
+
data: {
|
|
91
|
+
$set: {
|
|
92
|
+
settings: encrypt({
|
|
93
|
+
...settings,
|
|
94
|
+
adminAccessToken,
|
|
95
|
+
refreshToken: newRefreshToken,
|
|
96
|
+
refreshTokenExpiresAt,
|
|
97
|
+
tokenExpiresAt
|
|
98
|
+
})
|
|
83
99
|
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
collection: "action",
|
|
88
|
-
data: {
|
|
89
|
-
completedAt: /* @__PURE__ */ new Date(),
|
|
90
|
-
error: null,
|
|
91
|
-
errorStatus: null,
|
|
92
|
-
organization: connection.organization,
|
|
93
|
-
request: null,
|
|
94
|
-
response: null,
|
|
95
|
-
slug: "action.shopify.token.refresh",
|
|
96
|
-
status: "succeeded",
|
|
97
|
-
trigger: {
|
|
98
|
-
data: {
|
|
99
|
-
connection: connection.id
|
|
100
|
-
},
|
|
101
|
-
event: "shopify.token"
|
|
102
|
-
},
|
|
103
|
-
usage: null,
|
|
104
|
-
workflow: tokenWorkflow.id
|
|
105
|
-
},
|
|
106
|
-
options
|
|
107
|
-
});
|
|
100
|
+
},
|
|
101
|
+
query: {
|
|
102
|
+
id: credential.id
|
|
108
103
|
}
|
|
109
|
-
;
|
|
110
104
|
});
|
|
111
105
|
return adminAccessToken;
|
|
112
106
|
};
|
|
113
107
|
var getAdminToken = async ({ connection, controller }) => {
|
|
114
|
-
|
|
115
|
-
|
|
108
|
+
if (!(connection == null ? void 0 : connection.credential)) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
;
|
|
112
|
+
const settings = await resolveConnectionSettings({ connection, controller });
|
|
113
|
+
const { adminAccessToken, refreshToken, tokenExpiresAt } = settings;
|
|
114
|
+
if (!refreshToken) {
|
|
115
|
+
return adminAccessToken;
|
|
116
|
+
}
|
|
117
|
+
;
|
|
118
|
+
const needsRefresh = !tokenExpiresAt || new Date(tokenExpiresAt) < new Date(Date.now() + ACCESS_TOKEN_REFRESH_BUFFER_MS);
|
|
116
119
|
if (needsRefresh) {
|
|
117
120
|
return refreshAdminToken({ connection, controller });
|
|
118
121
|
}
|
|
122
|
+
;
|
|
119
123
|
return adminAccessToken;
|
|
120
124
|
};
|
|
121
125
|
export {
|
|
122
126
|
getAdminToken,
|
|
123
|
-
|
|
127
|
+
ping,
|
|
128
|
+
refreshAdminToken,
|
|
129
|
+
resolveConnectionSettings
|
|
124
130
|
};
|
package/package.json
CHANGED