MCPcopy Index your code
hub / github.com/ether/etherpad / expressCreateServer

Function expressCreateServer

src/node/hooks/express/updateStatus.ts:127–224  ·  view source on GitHub ↗
(
  _hookName: string,
  {app}: ArgsExpressType,
  cb: Function,
)

Source from the content-addressed store, hash-verified

125};
126
127export const expressCreateServer = (
128 _hookName: string,
129 {app}: ArgsExpressType,
130 cb: Function,
131): void => {
132 // Tier "off" disables the entire updater feature, including its HTTP surface.
133 if (settings.updates.tier === 'off') return cb();
134
135 // Public endpoint. Cached for 60s per (padId, authorId) key.
136 app.get('/api/version-status', wrapAsync(async (req, res) => {
137 const padId = typeof req.query.padId === 'string' ? req.query.padId : null;
138 const authorId = await resolveRequestAuthor(req);
139 const key = `${padId ?? ''}|${authorId ?? ''}`;
140 const now = Date.now();
141
142 const hit = cache.get(key);
143 if (hit && now - hit.at <= TTL_MS) {
144 res.json(hit.value);
145 return;
146 }
147
148 let flight = inFlight.get(key);
149 if (!flight) {
150 flight = computeOutdated(padId, authorId).finally(() => { inFlight.delete(key); });
151 inFlight.set(key, flight);
152 }
153 const value = await flight;
154 cache.set(key, {value, at: now});
155 res.json(value);
156 }));
157
158 // Admin UI status endpoint. By default this is open: the running version is already
159 // exposed publicly via /health, and latest/changelog come from a public GitHub
160 // release. Admins who want the endpoint gated to authenticated admin sessions —
161 // without disabling the updater entirely — set updates.requireAdminForStatus=true.
162 app.get('/admin/update/status', wrapAsync(async (req, res) => {
163 const isAdmin = !!req.session?.user?.is_admin;
164 if (settings.updates.requireAdminForStatus) {
165 const user = req.session?.user;
166 if (!user) return res.status(401).send('Authentication required');
167 if (!user.is_admin) return res.status(403).send('Forbidden');
168 }
169 const state = await loadState(stateFilePath());
170 const current = getEpVersion();
171 const installMethod = getDetectedInstallMethod();
172 const policy = state.latest
173 ? evaluatePolicy({
174 installMethod,
175 tier: settings.updates.tier,
176 current,
177 latest: state.latest.version,
178 executionStatus: state.execution.status,
179 maintenanceWindow: settings.updates.maintenanceWindow,
180 })
181 : null;
182 const lockHeld = await isHeld(path.join(settings.root, 'var', 'update.lock'));
183 // Tier 4: surface the configured window + the next opening so the admin UI
184 // can render the picker and the "deferred until..." subtitle on the

Callers 1

Calls 15

loadStateFunction · 0.90
stateFilePathFunction · 0.90
getEpVersionFunction · 0.90
getDetectedInstallMethodFunction · 0.90
evaluatePolicyFunction · 0.90
isHeldFunction · 0.90
parseWindowFunction · 0.90
nextWindowStartFunction · 0.90
resolveRequestAuthorFunction · 0.85
computeOutdatedFunction · 0.85
sanitizeExecutionFunction · 0.85
sanitizeLastResultFunction · 0.85

Tested by

no test coverage detected