diff --git a/.gitignore b/.gitignore index 8ee54e8..528a1cf 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ coverage *.sw? *.tsbuildinfo +*.lockb diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index fdb4970..ac381a7 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -9,7 +9,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { - + implementation project(':capacitor-preferences') } diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 9a5fa87..a1c665a 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -1,3 +1,6 @@ // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN include ':capacitor-android' project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') + +include ':capacitor-preferences' +project(':capacitor-preferences').projectDir = new File('../node_modules/@capacitor/preferences/android') diff --git a/bun.lockb b/bun.lockb deleted file mode 100755 index b4652ac..0000000 Binary files a/bun.lockb and /dev/null differ diff --git a/index.html b/index.html index 809b29c..ba5c5aa 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Solarplaza + Solian
diff --git a/ios/App/App/Info.plist b/ios/App/App/Info.plist index e084545..3c7a5b1 100644 --- a/ios/App/App/Info.plist +++ b/ios/App/App/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion en CFBundleDisplayName - @hydrogen/solaragent + Solian CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/ios/App/Podfile b/ios/App/Podfile index c66ecd4..e403f39 100644 --- a/ios/App/Podfile +++ b/ios/App/Podfile @@ -11,7 +11,7 @@ install! 'cocoapods', :disable_input_output_paths => true def capacitor_pods pod 'Capacitor', :path => '../../node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' - + pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences' end target 'App' do diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock index 95ebdcf..79c172c 100644 --- a/ios/App/Podfile.lock +++ b/ios/App/Podfile.lock @@ -2,21 +2,27 @@ PODS: - Capacitor (5.7.4): - CapacitorCordova - CapacitorCordova (5.7.4) + - CapacitorPreferences (5.0.7): + - Capacitor DEPENDENCIES: - "Capacitor (from `../../node_modules/@capacitor/ios`)" - "CapacitorCordova (from `../../node_modules/@capacitor/ios`)" + - "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)" EXTERNAL SOURCES: Capacitor: :path: "../../node_modules/@capacitor/ios" CapacitorCordova: :path: "../../node_modules/@capacitor/ios" + CapacitorPreferences: + :path: "../../node_modules/@capacitor/preferences" SPEC CHECKSUMS: Capacitor: 4fe9adf012caceb4c71ffea2f1f4d005cdcbeea7 CapacitorCordova: a6e87fccc0307dee7aec1560ec9398485f2b0ce7 + CapacitorPreferences: 77ac427e98db83bace772455f8ba447430382c4c -PODFILE CHECKSUM: 8ab55909c5de2b217f9841e5e5b329f5ec901553 +PODFILE CHECKSUM: 769e120bf4dfe4ef1095b83775e36bafeeeb3cdd COCOAPODS: 1.15.1 diff --git a/package.json b/package.json index 7a4fc9f..b51ed40 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@capacitor/android": "^5.7.4", "@capacitor/core": "^5.7.4", "@capacitor/ios": "^5.7.4", + "@capacitor/preferences": "^5.0.7", "@fontsource/roboto": "^5.0.12", "@mdi/font": "^7.4.47", "dompurify": "^3.0.11", diff --git a/src/components/Copyright.vue b/src/components/Copyright.vue new file mode 100644 index 0000000..f3f6baa --- /dev/null +++ b/src/components/Copyright.vue @@ -0,0 +1,6 @@ + diff --git a/src/components/NotificationList.vue b/src/components/NotificationList.vue new file mode 100644 index 0000000..32119a1 --- /dev/null +++ b/src/components/NotificationList.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/components/UserMenu.vue b/src/components/UserMenu.vue new file mode 100644 index 0000000..10a1c28 --- /dev/null +++ b/src/components/UserMenu.vue @@ -0,0 +1,43 @@ + + + diff --git a/src/components/auth/AccountLocator.vue b/src/components/auth/AccountLocator.vue new file mode 100644 index 0000000..aff510e --- /dev/null +++ b/src/components/auth/AccountLocator.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/components/auth/CallbackNotify.vue b/src/components/auth/CallbackNotify.vue new file mode 100644 index 0000000..d63c6d6 --- /dev/null +++ b/src/components/auth/CallbackNotify.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/auth/FactorApplicator.vue b/src/components/auth/FactorApplicator.vue new file mode 100644 index 0000000..85f7ff0 --- /dev/null +++ b/src/components/auth/FactorApplicator.vue @@ -0,0 +1,139 @@ + + + diff --git a/src/components/auth/FactorPicker.vue b/src/components/auth/FactorPicker.vue new file mode 100644 index 0000000..cd8b4fd --- /dev/null +++ b/src/components/auth/FactorPicker.vue @@ -0,0 +1,75 @@ + + + diff --git a/src/components/posts/PostReaction.vue b/src/components/posts/PostReaction.vue index 1622d14..bfacece 100644 --- a/src/components/posts/PostReaction.vue +++ b/src/components/posts/PostReaction.vue @@ -68,7 +68,7 @@ const error = ref(null) async function reactPost(symbol: string, attitude: number) { const res = await request("interactive", `/api/p/${props.model}/${props.item?.id}/react`, { method: "POST", - headers: { Authorization: `Bearer ${getAtk()}`, "Content-Type": "application/json" }, + headers: { Authorization: `Bearer ${await getAtk()}`, "Content-Type": "application/json" }, body: JSON.stringify({ symbol, attitude }) }) if (res.status === 201) { diff --git a/src/components/publish/ArticleEditor.vue b/src/components/publish/ArticleEditor.vue index 8e4727e..fffc585 100644 --- a/src/components/publish/ArticleEditor.vue +++ b/src/components/publish/ArticleEditor.vue @@ -184,7 +184,7 @@ async function postArticle(evt: SubmitEvent) { loading.value = true const res = await request("interactive", url, { method: method, - headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` }, body: JSON.stringify(payload) }) if (res.status === 200) { diff --git a/src/components/publish/CommentEditor.vue b/src/components/publish/CommentEditor.vue index a2482d9..de4a4a5 100644 --- a/src/components/publish/CommentEditor.vue +++ b/src/components/publish/CommentEditor.vue @@ -65,7 +65,7 @@ async function postComment(evt: SubmitEvent) { loading.value = true const res = await request("interactive", url, { method: method, - headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` }, body: JSON.stringify(payload) }) if (res.status === 200) { diff --git a/src/components/publish/MomentEditor.vue b/src/components/publish/MomentEditor.vue index aca7a48..5135881 100644 --- a/src/components/publish/MomentEditor.vue +++ b/src/components/publish/MomentEditor.vue @@ -131,7 +131,7 @@ async function postMoment(evt: SubmitEvent) { loading.value = true const res = await request("interactive", url, { method: method, - headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` }, body: JSON.stringify(payload) }) if (res.status === 200) { diff --git a/src/components/publish/PostDeletion.vue b/src/components/publish/PostDeletion.vue index fa3be14..f578839 100644 --- a/src/components/publish/PostDeletion.vue +++ b/src/components/publish/PostDeletion.vue @@ -38,7 +38,7 @@ async function deletePost() { loading.value = true const res = await request("interactive", url, { method: "DELETE", - headers: { Authorization: `Bearer ${getAtk()}` } + headers: { Authorization: `Bearer ${await getAtk()}` } }) if (res.status !== 200) { error.value = await res.text() diff --git a/src/components/publish/parts/Media.vue b/src/components/publish/parts/Media.vue index 7ee7ac9..42a7cf7 100644 --- a/src/components/publish/parts/Media.vue +++ b/src/components/publish/parts/Media.vue @@ -65,7 +65,7 @@ async function upload(file?: any) { emits("update:uploading", true) const res = await request("interactive", "/api/attachments", { method: "POST", - headers: { Authorization: `Bearer ${getAtk()}` }, + headers: { Authorization: `Bearer ${await getAtk()}` }, body: data }) let meta: any @@ -87,7 +87,7 @@ async function dispose(idx: number) { const res = await request("interactive", `/api/attachments/${item.id}`, { method: "DELETE", - headers: { Authorization: `Bearer ${getAtk()}` } + headers: { Authorization: `Bearer ${await getAtk()}` } }) if (res.status !== 200) { error.value = await res.text() diff --git a/src/components/realms/RealmDeletion.vue b/src/components/realms/RealmDeletion.vue index 51beca5..0af3091 100644 --- a/src/components/realms/RealmDeletion.vue +++ b/src/components/realms/RealmDeletion.vue @@ -43,7 +43,7 @@ async function deletePost() { loading.value = true const res = await request("interactive", url, { method: "DELETE", - headers: { Authorization: `Bearer ${getAtk()}` } + headers: { Authorization: `Bearer ${await getAtk()}` } }) if (res.status !== 200) { error.value = await res.text() diff --git a/src/components/realms/RealmEditor.vue b/src/components/realms/RealmEditor.vue index 5b6884a..051fa51 100644 --- a/src/components/realms/RealmEditor.vue +++ b/src/components/realms/RealmEditor.vue @@ -63,7 +63,7 @@ async function submit(evt: SubmitEvent) { loading.value = true const res = await request("interactive", url, { method: method, - headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` }, body: JSON.stringify(payload) }) if (res.status !== 200) { diff --git a/src/components/realms/RealmInvitation.vue b/src/components/realms/RealmInvitation.vue index 683d6f7..d13b2af 100644 --- a/src/components/realms/RealmInvitation.vue +++ b/src/components/realms/RealmInvitation.vue @@ -38,7 +38,7 @@ async function inviteMember(evt: SubmitEvent) { loading.value = true const res = await request("interactive", `/api/realms/${props.item?.id}/invite`, { method: "POST", - headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` }, body: JSON.stringify({ account_name: targetName.value }) diff --git a/src/components/realms/RealmMembers.vue b/src/components/realms/RealmMembers.vue index 410e1df..9abc0f6 100644 --- a/src/components/realms/RealmMembers.vue +++ b/src/components/realms/RealmMembers.vue @@ -97,7 +97,7 @@ async function kickMember(item: any) { loading.value = true const res = await request("interactive", `/api/realms/${props.item?.id}/kick`, { method: "POST", - headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` }, body: JSON.stringify({ account_name: item.account.name }) diff --git a/src/index.vue b/src/index.vue index e068d9d..d4637e1 100644 --- a/src/index.vue +++ b/src/index.vue @@ -7,10 +7,14 @@ diff --git a/src/layouts/master.vue b/src/layouts/master.vue index 914d0c2..dc9155e 100644 --- a/src/layouts/master.vue +++ b/src/layouts/master.vue @@ -40,7 +40,7 @@ - + @@ -139,9 +139,6 @@ id.readProfiles() const meta = useWellKnown() -const signinUrl = computed(() => { - return meta.wellKnown?.components?.identity + `/auth/sign-in?redirect_uri=${encodeURIComponent(location.href)}` -}) const passportUrl = computed(() => { return meta.wellKnown?.components?.identity }) diff --git a/src/router/index.ts b/src/router/index.ts index 3ce9642..cccefa6 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -29,6 +29,24 @@ const router = createRouter({ path: "/realms/:realmId", name: "realms.page", component: () => import("@/views/realms/page.vue") + }, + + { + path: "/auth", + children: [ + { + path: "sign-in", + name: "auth.sign-in", + component: () => import("@/views/auth/sign-in.vue"), + meta: { public: true, title: "Sign in" } + }, + { + path: "sign-up", + name: "auth.sign-up", + component: () => import("@/views/auth/sign-up.vue"), + meta: { public: true, title: "Sign up" } + } + ] } ] } diff --git a/src/stores/realms.ts b/src/stores/realms.ts index 633a8ee..ab13adf 100644 --- a/src/stores/realms.ts +++ b/src/stores/realms.ts @@ -19,10 +19,10 @@ export const useRealms = defineStore("realms", () => { const available = ref([]) async function list() { - if (!checkLoggedIn()) return + if (!(await checkLoggedIn())) return const res = await request("interactive", "/api/realms/me/available", { - headers: { Authorization: `Bearer ${getAtk()}` } + headers: { Authorization: `Bearer ${await getAtk()}` } }) if (res.status !== 200) { throw new Error(await res.text()) diff --git a/src/stores/userinfo.ts b/src/stores/userinfo.ts index 9f38c80..d0de4ee 100644 --- a/src/stores/userinfo.ts +++ b/src/stores/userinfo.ts @@ -1,7 +1,7 @@ -import Cookie from "universal-cookie" import { defineStore } from "pinia" import { ref } from "vue" import { request } from "@/scripts/request" +import { Preferences } from "@capacitor/preferences" export interface Userinfo { isReady: boolean @@ -17,12 +17,12 @@ const defaultUserinfo: Userinfo = { data: null } -export function getAtk(): string { - return new Cookie().get("identity_auth_key") +export async function getAtk() { + return (await Preferences.get({ key: "identity.access_token" })).value } -export function checkLoggedIn(): boolean { - return new Cookie().get("identity_auth_key") +export async function checkLoggedIn(): boolean { + return (await Preferences.get({ key: "identity.access_token" })).value != null } export const useUserinfo = defineStore("userinfo", () => { @@ -30,12 +30,12 @@ export const useUserinfo = defineStore("userinfo", () => { const isReady = ref(false) async function readProfiles() { - if (!checkLoggedIn()) { + if (!(await checkLoggedIn())) { isReady.value = true } - const res = await request("interactive", "/api/users/me", { - headers: { Authorization: `Bearer ${getAtk()}` } + const res = await request("identity", "/api/users/me", { + headers: { Authorization: `Bearer ${await getAtk()}` } }) if (res.status !== 200) { diff --git a/src/views/auth/sign-in.vue b/src/views/auth/sign-in.vue new file mode 100644 index 0000000..7f7388b --- /dev/null +++ b/src/views/auth/sign-in.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/src/views/auth/sign-up.vue b/src/views/auth/sign-up.vue new file mode 100644 index 0000000..eddf9e7 --- /dev/null +++ b/src/views/auth/sign-up.vue @@ -0,0 +1,162 @@ + + + + +