Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note_extension
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note_extension
Commits
ba521e44
Commit
ba521e44
authored
Apr 28, 2026
by
Vũ Hoàng Anh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add support for syncing tokens from standard Memos instances
parent
7745c72d
Pipeline
#3443
failed with stages
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
59 additions
and
10 deletions
+59
-10
manifest.json
extension/dist/.vite/manifest.json
+3
-3
manifest.json
extension/dist/manifest.json
+2
-2
service-worker-loader.js
extension/dist/service-worker-loader.js
+1
-1
popup.html
extension/dist/src/popup/popup.html
+1
-1
service-worker.ts
extension/src/background/service-worker.ts
+17
-1
content-script.ts
extension/src/content/content-script.ts
+18
-1
popup.tsx
extension/src/popup/popup.tsx
+17
-1
No files found.
extension/dist/.vite/manifest.json
View file @
ba521e44
...
...
@@ -10,7 +10,7 @@
"name"
:
"api-client"
},
"src/background/service-worker.ts"
:
{
"file"
:
"assets/service-worker.ts-D
VsIrub1
.js"
,
"file"
:
"assets/service-worker.ts-D
vMHIkFe
.js"
,
"name"
:
"service-worker.ts"
,
"src"
:
"src/background/service-worker.ts"
,
"isEntry"
:
true
,
...
...
@@ -19,13 +19,13 @@
]
},
"src/content/content-script.ts"
:
{
"file"
:
"assets/content-script.ts-
Kz-gf73N
.js"
,
"file"
:
"assets/content-script.ts-
BWL85FVS
.js"
,
"name"
:
"content-script.ts"
,
"src"
:
"src/content/content-script.ts"
,
"isEntry"
:
true
},
"src/popup/popup.html"
:
{
"file"
:
"assets/popup-
bQfbpxZ8
.js"
,
"file"
:
"assets/popup-
DmXuB8QF
.js"
,
"name"
:
"popup"
,
"src"
:
"src/popup/popup.html"
,
"isEntry"
:
true
,
...
...
extension/dist/manifest.json
View file @
ba521e44
...
...
@@ -20,7 +20,7 @@
"content_scripts"
:
[
{
"js"
:
[
"assets/content-script.ts-
Kz-gf73N
.js"
"assets/content-script.ts-
BWL85FVS
.js"
],
"matches"
:
[
"<all_urls>"
...
...
@@ -48,7 +48,7 @@
"<all_urls>"
],
"resources"
:
[
"assets/content-script.ts-
Kz-gf73N
.js"
"assets/content-script.ts-
BWL85FVS
.js"
],
"use_dynamic_url"
:
false
}
...
...
extension/dist/service-worker-loader.js
View file @
ba521e44
import
'./assets/service-worker.ts-D
VsIrub1
.js'
;
import
'./assets/service-worker.ts-D
vMHIkFe
.js'
;
extension/dist/src/popup/popup.html
View file @
ba521e44
...
...
@@ -17,7 +17,7 @@
overflow-y
:
auto
;
}
</style>
<script
type=
"module"
crossorigin
src=
"/assets/popup-
bQfbpxZ8
.js"
></script>
<script
type=
"module"
crossorigin
src=
"/assets/popup-
DmXuB8QF
.js"
></script>
<link
rel=
"modulepreload"
crossorigin
href=
"/assets/api-client-Y5oDKlCr.js"
>
<link
rel=
"stylesheet"
crossorigin
href=
"/assets/popup-dYtSf2jU.css"
>
</head>
...
...
extension/src/background/service-worker.ts
View file @
ba521e44
...
...
@@ -33,11 +33,27 @@ async function grabFreshToken(): Promise<string | null> {
world
:
'MAIN'
,
func
:
async
()
=>
{
try
{
// 1. Try Memos cookie
const
match
=
document
.
cookie
.
match
(
/
(?:
^|;
)
memos
\.
access-token=
([^
;
]
+
)
/
);
if
(
match
&&
match
[
1
])
return
match
[
1
];
// 2. Try localStorage
for
(
let
i
=
0
;
i
<
localStorage
.
length
;
i
++
)
{
const
key
=
localStorage
.
key
(
i
);
if
(
key
&&
(
key
.
includes
(
'token'
)
||
key
.
includes
(
'session'
)))
{
const
val
=
localStorage
.
getItem
(
key
);
if
(
val
&&
typeof
val
===
'string'
&&
val
.
length
>
50
&&
!
val
.
startsWith
(
'{'
))
{
return
val
;
}
}
}
// 3. Try Clerk
const
clerk
=
(
window
as
any
).
Clerk
;
if
(
clerk
?.
session
?.
getToken
)
{
return
await
clerk
.
session
.
getToken
();
}
}
catch
{
/*
Clerk not availabl
e */
}
}
catch
{
/*
ignor
e */
}
return
null
;
},
});
...
...
extension/src/content/content-script.ts
View file @
ba521e44
...
...
@@ -21,6 +21,23 @@ async function tryExtractClerkToken(): Promise<string | null> {
for
(
let
attempt
=
0
;
attempt
<
maxRetries
;
attempt
++
)
{
try
{
// 1. Try Memos cookie
const
match
=
document
.
cookie
.
match
(
/
(?:
^|;
)
memos
\.
access-token=
([^
;
]
+
)
/
);
if
(
match
&&
match
[
1
])
return
match
[
1
];
// 2. Try Memos API token from localStorage (if any)
for
(
let
i
=
0
;
i
<
localStorage
.
length
;
i
++
)
{
const
key
=
localStorage
.
key
(
i
);
if
(
key
&&
(
key
.
includes
(
'token'
)
||
key
.
includes
(
'session'
)))
{
const
val
=
localStorage
.
getItem
(
key
);
if
(
val
&&
typeof
val
===
'string'
&&
val
.
length
>
50
&&
!
val
.
startsWith
(
'{'
))
{
// Return if looks like a JWT or long token
return
val
;
}
}
}
// 3. Try Clerk token
const
clerk
=
(
window
as
any
).
Clerk
;
// Skip if Clerk loaded but user not signed in
if
(
clerk
&&
!
clerk
.
user
)
return
null
;
...
...
@@ -29,7 +46,7 @@ async function tryExtractClerkToken(): Promise<string | null> {
if
(
token
)
return
token
;
}
}
catch
{
// Clerk chưa ready, thử lại
// Clerk
/Memos
chưa ready, thử lại
}
if
(
attempt
<
maxRetries
-
1
)
{
...
...
extension/src/popup/popup.tsx
View file @
ba521e44
...
...
@@ -67,11 +67,27 @@ async function grabTokenFromTabs(): Promise<string | null> {
world
:
'MAIN'
,
func
:
async
()
=>
{
try
{
// 1. Try Memos cookie
const
match
=
document
.
cookie
.
match
(
/
(?:
^|;
)
memos
\.
access-token=
([^
;
]
+
)
/
);
if
(
match
&&
match
[
1
])
return
match
[
1
];
// 2. Try localStorage
for
(
let
i
=
0
;
i
<
localStorage
.
length
;
i
++
)
{
const
key
=
localStorage
.
key
(
i
);
if
(
key
&&
(
key
.
includes
(
'token'
)
||
key
.
includes
(
'session'
)))
{
const
val
=
localStorage
.
getItem
(
key
);
if
(
val
&&
typeof
val
===
'string'
&&
val
.
length
>
50
&&
!
val
.
startsWith
(
'{'
))
{
return
val
;
}
}
}
// 3. Try Clerk
const
clerk
=
(
window
as
any
).
Clerk
;
if
(
clerk
?.
session
?.
getToken
)
{
return
await
clerk
.
session
.
getToken
();
}
}
catch
{
/*
Clerk not availabl
e */
}
}
catch
{
/*
ignor
e */
}
return
null
;
},
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment