@raketa-cloud/admin 0.0.86 → 0.0.88

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raketa-cloud/admin",
3
- "version": "0.0.86",
3
+ "version": "0.0.88",
4
4
  "main": "src/index.js",
5
5
  "scripts": {
6
6
  "dev": "npx tailwindcss -i ./src/styles/application.css -o ../../apps/admin/static/application.css --watch",
@@ -17,7 +17,7 @@ const AuthHelper = {
17
17
  },
18
18
 
19
19
  isAuthenticated: ({ path, token }) => {
20
- const ALLOWED_PATHS = ["/login", "/auth/google/callback"];
20
+ const ALLOWED_PATHS = ["/login", "/auth/google/callback", "/remote/verify"];
21
21
 
22
22
  if (ALLOWED_PATHS.includes(path)) return true;
23
23
 
@@ -1,7 +1,45 @@
1
+ import { createHmac, randomBytes } from "node:crypto";
1
2
  import ejs from "ejs";
2
3
  import { deleteCookie, getCookie, setCookie } from "hono/cookie";
3
4
  import currentPath from "./currentPath.cjs";
4
5
  import AuthHelper from "./helpers/AuthHelper";
6
+ // TODO: Maybe change the encryption mechanism?
7
+ import simpleCipher from "./simpleCipher";
8
+
9
+ // Generate a random signing secret on every server restart
10
+ const SIGNING_SECRET = randomBytes(64).toString("hex");
11
+ const DELIMITER = ",";
12
+
13
+ function calculateHash(text) {
14
+ return createHmac("sha256", SIGNING_SECRET).update(text).digest("hex");
15
+ }
16
+
17
+ function obfuscateToken(token) {
18
+ const date = new Date();
19
+ const timestamp = date.getTime() + 2 * 60000;
20
+ const timestamped = [token, timestamp].join(DELIMITER);
21
+ const hash = calculateHash(timestamped);
22
+ const signed = [hash, timestamped].join(DELIMITER);
23
+
24
+ return Buffer.from(simpleCipher.encrypt(signed)).toString("base64");
25
+ }
26
+
27
+ function extractToken(text) {
28
+ const encrypted = Buffer.from(text, "base64").toString("ascii");
29
+ const signed = simpleCipher.decrypt(encrypted);
30
+ const [hash, token, timestamp] = signed.split(DELIMITER);
31
+ const tDate = new Date(Number.parseInt(timestamp, 10));
32
+
33
+ if (tDate < new Date()) {
34
+ return null;
35
+ }
36
+
37
+ if (hash !== calculateHash([token, timestamp].join(DELIMITER))) {
38
+ return null;
39
+ }
40
+
41
+ return token;
42
+ }
5
43
 
6
44
  function getAuthBearer(c) {
7
45
  const authHeader = c.req.header("Authorization") || "";
@@ -9,6 +47,15 @@ function getAuthBearer(c) {
9
47
  return authHeader.replace("Bearer", "").trim();
10
48
  }
11
49
 
50
+ function unauthorized() {
51
+ return new Response("Unauthorized", {
52
+ status: 401,
53
+ headers: {
54
+ Authenticate: 'error="invalid_token"',
55
+ },
56
+ });
57
+ }
58
+
12
59
  const setupAuthentication = (app, config) => {
13
60
  app.use(async (c, next) => {
14
61
  const token = getCookie(c, AuthHelper.cookie_key) || getAuthBearer(c);
@@ -56,54 +103,66 @@ const setupAuthentication = (app, config) => {
56
103
  if (!active) return c.redirect("/login?err=not_activated");
57
104
 
58
105
  const isLocalhost = c.req.url.includes("http://localhost");
106
+
59
107
  setCookie(c, AuthHelper.cookie_key, token, {
60
108
  path: "/",
61
109
  httpOnly: true,
62
110
  secure: !isLocalhost,
63
111
  });
64
112
 
65
- return c.redirect("/en");
113
+ return c.redirect("/remote/login");
66
114
  });
67
115
 
68
116
  app.get("/logout", (c) => {
69
117
  deleteCookie(c, AuthHelper.cookie_key);
70
- return c.redirect("/login");
118
+
119
+ return c.redirect(config.remoteConfig.remoteLogout);
71
120
  });
72
121
 
73
122
  // Routes related to the remote project handling
74
- app.get("/remote-login", (c) => {
123
+ app.get("/profile", (c) => {
124
+ const token = getAuthBearer(c);
125
+
126
+ // TODO: Here we may update the Gateway API to have the check dynamically done in the backend!
127
+ if (AuthHelper.verifyJWT(token)) {
128
+ return c.json({ message: "OK" });
129
+ } else {
130
+ return unauthorized();
131
+ }
132
+ });
133
+
134
+ app.get("/remote/login", (c) => {
75
135
  const token = getCookie(c, AuthHelper.cookie_key);
76
136
 
77
137
  if (!AuthHelper.verifyJWT(token)) {
78
138
  return c.redirect("/login");
79
139
  }
80
140
 
81
- // TODO: Figure out how to change this so it is secure!
141
+ const ot = obfuscateToken(token);
142
+
143
+ console.log({ ot });
144
+
82
145
  return c.redirect(
83
146
  [
84
147
  config.remoteConfig.remoteLogin,
85
148
  "?redirect_to=",
86
149
  c.req.query().redirect_to,
87
- "&page_snapshot=",
88
- token,
150
+ "&snapshot=",
151
+ obfuscateToken(token),
89
152
  ].join("")
90
153
  );
91
154
  });
92
155
 
93
- app.get("/profile", (c) => {
94
- const token = getAuthBearer(c);
156
+ app.post("/remote/verify", async (c) => {
157
+ const { credentials } = await c.req.json();
95
158
 
96
- // TODO: Here we may update the Gateway API to have the check dynamically done in the backend!
97
- if (AuthHelper.verifyJWT(token)) {
98
- return c.json({ message: "OK" });
99
- } else {
100
- return new Response("Unauthorized", {
101
- status: 401,
102
- headers: {
103
- Authenticate: 'error="invalid_token"',
104
- },
105
- });
159
+ const token = extractToken(credentials);
160
+
161
+ if (!token) {
162
+ return unauthorized();
106
163
  }
164
+
165
+ return c.json({ token });
107
166
  });
108
167
  };
109
168
 
@@ -0,0 +1,54 @@
1
+ const ALPHABET =
2
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.";
3
+
4
+ function generateKey() {
5
+ const shuffled = ALPHABET.split("")
6
+ .sort(() => Math.random() - 0.5)
7
+ .join("");
8
+
9
+ return shuffled;
10
+ }
11
+
12
+ function generateEncryptionLookup(key) {
13
+ const lookup = {};
14
+
15
+ ALPHABET.split("").forEach((char, index) => {
16
+ lookup[char] = key[index];
17
+ });
18
+
19
+ return lookup;
20
+ }
21
+
22
+ function generateDecryptionLookup(key) {
23
+ const lookup = {};
24
+
25
+ key.split("").forEach((char, index) => {
26
+ lookup[char] = ALPHABET[index];
27
+ });
28
+
29
+ return lookup;
30
+ }
31
+
32
+ // Scramble lookup maps on every server restart
33
+ const CIPHER_KEY = generateKey();
34
+ const ENCRYPT_LOOKUP = generateEncryptionLookup(CIPHER_KEY);
35
+ const DECRYPT_LOOKUP = generateDecryptionLookup(CIPHER_KEY);
36
+
37
+ function encrypt(plaintext) {
38
+ return plaintext
39
+ .split("")
40
+ .map((char) => ENCRYPT_LOOKUP[char] || char)
41
+ .join("");
42
+ }
43
+
44
+ function decrypt(ciphertext) {
45
+ return ciphertext
46
+ .split("")
47
+ .map((char) => DECRYPT_LOOKUP[char] || char)
48
+ .join("");
49
+ }
50
+
51
+ export default {
52
+ encrypt,
53
+ decrypt,
54
+ };
@@ -12,7 +12,7 @@
12
12
  </form>
13
13
  <% } %>
14
14
 
15
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleTypePlural %>/<%= resource.id %>/changes/<%= change.version %>" class="btn-text has-icon">
15
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleTypePlural %>/<%= resource.id %>/changes/<%= change.version %>" class="btn-text has-icon">
16
16
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
17
17
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
18
18
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -20,4 +20,4 @@
20
20
 
21
21
  Preview
22
22
  </a>
23
- </div>
23
+ </div>
@@ -1,5 +1,5 @@
1
1
  <div class="actions-toolbar justify-end">
2
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= revision.id %>/builder" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
2
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= revision.id %>/builder" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
3
3
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
5
5
  </svg>
@@ -31,7 +31,7 @@
31
31
  Edit settings
32
32
  </a>
33
33
 
34
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
34
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
35
35
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
36
36
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
37
37
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -199,7 +199,7 @@
199
199
  Delete
200
200
  </button>
201
201
 
202
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
202
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
203
203
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
204
204
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
205
205
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -1,5 +1,5 @@
1
1
  <div class="actions-toolbar justify-end">
2
- <a href="/remote-login?redirect_to=/<%= translation.translationLocale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= translation.revisionId %>/builder" class="btn-text has-icon">
2
+ <a href="/remote/login?redirect_to=/<%= translation.translationLocale %>/admin/<%= _context.resourceConfig.articleType %>-revisions/<%= translation.revisionId %>/builder" class="btn-text has-icon">
3
3
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
5
5
  </svg>
@@ -12,7 +12,7 @@
12
12
  </form>
13
13
  <% } %>
14
14
 
15
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventTypePlural %>/<%= resource.id %>/changes/<%= change.version %>" class="btn-text has-icon">
15
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventTypePlural %>/<%= resource.id %>/changes/<%= change.version %>" class="btn-text has-icon">
16
16
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
17
17
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
18
18
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -20,4 +20,4 @@
20
20
 
21
21
  Preview
22
22
  </a>
23
- </div>
23
+ </div>
@@ -1,5 +1,5 @@
1
1
  <div class="actions-toolbar justify-end">
2
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= revision.id %>/builder" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
2
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= revision.id %>/builder" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
3
3
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
5
5
  </svg>
@@ -31,7 +31,7 @@
31
31
  Edit settings
32
32
  </a>
33
33
 
34
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
34
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
35
35
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
36
36
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
37
37
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -199,7 +199,7 @@
199
199
  Delete
200
200
  </button>
201
201
 
202
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
202
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
203
203
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
204
204
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
205
205
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -1,5 +1,5 @@
1
1
  <div class="actions-toolbar justify-end">
2
- <a href="/remote-login?redirect_to=/<%= translation.translationLocale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= translation.revisionId %>/builder" class="btn-text has-icon">
2
+ <a href="/remote/login?redirect_to=/<%= translation.translationLocale %>/admin/<%= _context.resourceConfig.eventType %>-revisions/<%= translation.revisionId %>/builder" class="btn-text has-icon">
3
3
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
5
5
  </svg>
@@ -12,7 +12,7 @@
12
12
  </form>
13
13
  <% } %>
14
14
 
15
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageTypePlural %>/<%= resource.id %>/changes/<%= change.version %>" class="btn-text has-icon">
15
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageTypePlural %>/<%= resource.id %>/changes/<%= change.version %>" class="btn-text has-icon">
16
16
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
17
17
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
18
18
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -20,4 +20,4 @@
20
20
 
21
21
  Preview
22
22
  </a>
23
- </div>
23
+ </div>
@@ -1,5 +1,5 @@
1
1
  <div class="actions-toolbar justify-end">
2
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= revision.id %>/builder" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
2
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= revision.id %>/builder" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
3
3
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
5
5
  </svg>
@@ -31,7 +31,7 @@
31
31
  Edit settings
32
32
  </a>
33
33
 
34
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
34
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon <%= revision.meta && revision.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
35
35
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
36
36
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
37
37
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -200,7 +200,7 @@
200
200
  Delete
201
201
  </button>
202
202
 
203
- <a href="/remote-login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
203
+ <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
204
204
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
205
205
  <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
206
206
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
@@ -1,5 +1,5 @@
1
1
  <div class="actions-toolbar justify-end">
2
- <a href="/remote-login?redirect_to=/<%= translation.translationLocale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= translation.revisionId %>/builder" class="btn-text has-icon">
2
+ <a href="/remote/login?redirect_to=/<%= translation.translationLocale %>/admin/<%= _context.resourceConfig.pageType %>-revisions/<%= translation.revisionId %>/builder" class="btn-text has-icon">
3
3
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
5
5
  </svg>