Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
22b7e7a
feat: profile editor
sosweetham Mar 10, 2026
3fed651
fix: profile video download
sosweetham Mar 10, 2026
6bb1151
feat: dreamsync integration
sosweetham Mar 11, 2026
5208c35
fix: update lockfile
sosweetham Mar 11, 2026
2494790
merge: main
sosweetham Mar 11, 2026
2ab188f
fix: dreamsync profile patch
sosweetham Mar 12, 2026
f8242b4
fix: actions
sosweetham Mar 12, 2026
66fdbe5
fix: remove unused shad components
sosweetham Mar 12, 2026
f6e6dc9
fix: format
sosweetham Mar 12, 2026
fc38ef9
fix: build
sosweetham Mar 12, 2026
dcd1b74
fix: lockfile
sosweetham Mar 12, 2026
804fa61
fix: ai suggestions
sosweetham Mar 12, 2026
433d6ec
fix: add missing headers for file upload
Bekiboo Mar 12, 2026
cb38d7c
fix: update dependencies and clean up prepare script
Bekiboo Mar 12, 2026
5564eef
fix: normalize ACL entries and improve error handling in EVaultProfil…
Bekiboo Mar 12, 2026
2d0d7c2
fix: reorder and format dependencies in package.json
Bekiboo Mar 12, 2026
fa66ede
fix: enhance URL normalization and validation in SocialLinksSection
Bekiboo Mar 12, 2026
9ae7511
fix: update package dependencies in pnpm-lock.yaml for improved compa…
Bekiboo Mar 12, 2026
af9234b
fix: improve error handling for createMetaEnvelope in EVaultProfileSe…
Bekiboo Mar 12, 2026
248da7c
fix: enhance access control logic for profile assets in ProfileContro…
Bekiboo Mar 12, 2026
1055226
fix: normalize eName before setting in headers for GraphQLClient
Bekiboo Mar 12, 2026
827c2c0
fix: enhance educational and work experience sections with improved l…
Bekiboo Mar 13, 2026
065aba3
feat: add logo and favicon images for profile editor
Bekiboo Mar 13, 2026
5dccb39
fix: replace native select with custom Select component for platform …
Bekiboo Mar 13, 2026
ed99f88
resolve pnpm-lock.yaml merge conflict
Bekiboo Mar 13, 2026
2dfcadb
resolve pnpm-lock.yaml merge conflict with main
Bekiboo Mar 13, 2026
c01ccba
fix: lockfile merge conflicts
sosweetham Mar 16, 2026
2a54351
fix: dreamsync warns
sosweetham Mar 16, 2026
58132d9
fix: explicit pub priv profile behaviour
sosweetham Mar 16, 2026
24c7c64
fix: dreamsync profile visibility
sosweetham Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ PUBLIC_PROVISIONER_SHARED_SECRET="your-provisioner-shared-secret"

PUBLIC_ESIGNER_BASE_URL="http://localhost:3004"
PUBLIC_FILE_MANAGER_BASE_URL="http://localhost:3005"
PUBLIC_PROFILE_EDITOR_BASE_URL="http://localhost:3006"

DREAMSYNC_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/dreamsync
VITE_DREAMSYNC_BASE_URL="http://localhost:8888"
Expand Down
1 change: 0 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
optional=true
strict-peer-dependencies=false

8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Port Assignments

#### Core Services (Always Running)

- **4321** - Registry Service
- **3001** - evault-core Provisioning API (Express)
- **4000** - evault-core GraphQL/HTTP API (Fastify)
Expand All @@ -17,6 +18,7 @@
- **7687** - Neo4j Bolt Protocol

#### Platform APIs

- **3000** - Blabsy W3DS Auth API
- **3002** - Cerberus API
- **3003** - Group Charter Manager API
Expand All @@ -28,6 +30,7 @@
- **1111** - Pictique API

#### Frontend Services

- **8080** - Dev sandbox (W3DS) / Blabsy Frontend
- **5173** - Pictique Frontend
- **3004** - Group Charter Manager Frontend
Expand All @@ -37,19 +40,24 @@
### Docker Compose Profiles

#### `socials` Profile

Runs core services plus social media platforms:

- Core: registry, evault-core, postgres, neo4j
- Pictique API + Frontend
- Blabsy API + Frontend

#### `charter-blabsy` Profile

Runs core services plus charter and blabsy:

- Core: registry, evault-core, postgres, neo4j
- Group Charter Manager API + Frontend
- Blabsy API + Frontend
- Cerberus

#### `all` Profile

Runs all services (core + all APIs + all frontends)

### Usage
Expand Down
1 change: 1 addition & 0 deletions docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const config: Config = {
sidebarPath: './sidebars.ts',
editUrl: 'https://github.com/MetaState-Prototype-Project/prototype/tree/main/docs/',
},
blog: false,
} satisfies Preset.Options,
],
],
Expand Down
3 changes: 1 addition & 2 deletions infrastructure/control-panel/config/admin-enames.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"@7218b67d-da21-54d6-9a85-7c4db1d09768",
"@82f7a77a-f03a-52aa-88fc-1b1e488ad498",
"@35a31f0d-dd76-5780-b383-29f219fcae99",
"@82f7a77a-f03a-52aa-88fc-1b1e488ad498",
"@af7e4f55-ad9d-537c-81ef-4f3a234bdd2c"
"@82f7a77a-f03a-52aa-88fc-1b1e488ad498"
]
}
33 changes: 33 additions & 0 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@metastate-foundation/auth",
"version": "0.1.0",
"description": "Shared authentication utilities for w3ds platform APIs",
"type": "module",
"scripts": {
"build": "tsc -p tsconfig.json",
"check-types": "tsc --noEmit",
"postinstall": "npm run build"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"files": ["dist"],
"dependencies": {
"jsonwebtoken": "^9.0.2",
"signature-validator": "workspace:*",
"uuid": "^11.1.0"
},
"devDependencies": {
"@types/jsonwebtoken": "^9.0.9",
"@types/node": "^20.11.24",
"@types/uuid": "^10.0.0",
"typescript": "~5.6.2"
}
}
15 changes: 15 additions & 0 deletions packages/auth/src/auth-offer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { v4 as uuidv4 } from "uuid";
import type { AuthOfferConfig } from "./types.js";

export interface AuthOffer {
uri: string;
session: string;
}

export function buildAuthOffer(config: AuthOfferConfig): AuthOffer {
const callbackPath = config.callbackPath ?? "/api/auth";
const url = new URL(callbackPath, config.baseUrl).toString();
const session = uuidv4();
const uri = `w3ds://auth?redirect=${url}&session=${session}&platform=${config.platform}`;
return { uri, session };
}
8 changes: 8 additions & 0 deletions packages/auth/src/guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function createAuthGuard() {
return (req: any, res: any, next: any): void => {
if (!req.user) {
return res.status(401).json({ error: "Authentication required" });
}
next();
};
}
14 changes: 14 additions & 0 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export { signToken, verifyToken } from "./jwt.js";
export { createAuthMiddleware } from "./middleware.js";
export { createAuthGuard } from "./guard.js";
export { buildAuthOffer } from "./auth-offer.js";
export type { AuthOffer } from "./auth-offer.js";
export { verifyLoginSignature } from "./verify-login.js";
export type {
AuthUser,
JwtPayload,
AuthMiddlewareConfig,
AuthOfferConfig,
LoginVerificationConfig,
LoginVerificationResult,
} from "./types.js";
20 changes: 20 additions & 0 deletions packages/auth/src/jwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import jwt from "jsonwebtoken";
import type { JwtPayload } from "./types.js";

export function signToken(
payload: JwtPayload,
secret: string,
options?: { expiresIn?: string | number },
): string {
return jwt.sign(payload as object, secret, {
expiresIn: (options?.expiresIn ?? "7d") as any,
});
}

export function verifyToken(token: string, secret: string): JwtPayload {
try {
return jwt.verify(token, secret) as JwtPayload;
} catch {
throw new Error("Invalid token");
}
}
32 changes: 32 additions & 0 deletions packages/auth/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { verifyToken } from "./jwt.js";
import type { AuthMiddlewareConfig } from "./types.js";

export function createAuthMiddleware(config: AuthMiddlewareConfig) {
return async (req: any, res: any, next: any): Promise<void> => {
try {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer ")) {
return next();
}

const token = authHeader.split(" ")[1];
const decoded = verifyToken(token, config.secret);

if (!decoded?.userId) {
return res.status(401).json({ error: "Invalid token" });
}

const user = await config.findUser(decoded.userId);

if (!user) {
return res.status(401).json({ error: "User not found" });
}

req.user = user;
next();
} catch (error) {
console.error("Auth middleware error:", error);
res.status(401).json({ error: "Invalid token" });
}
};
}
34 changes: 34 additions & 0 deletions packages/auth/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export interface AuthUser {
id: string;
ename: string;
[key: string]: unknown;
}

export interface JwtPayload {
userId: string;
[key: string]: unknown;
}

export interface AuthMiddlewareConfig {
secret: string;
findUser: (userId: string) => Promise<AuthUser | null>;
}

export interface AuthOfferConfig {
baseUrl: string;
platform: string;
callbackPath?: string;
}

export interface LoginVerificationConfig {
eName: string;
signature: string;
session: string;
registryBaseUrl: string;
}

export interface LoginVerificationResult {
valid: boolean;
error?: string;
publicKey?: string;
}
22 changes: 22 additions & 0 deletions packages/auth/src/verify-login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { verifySignature } from "signature-validator";
import type {
LoginVerificationConfig,
LoginVerificationResult,
} from "./types.js";

export async function verifyLoginSignature(
config: LoginVerificationConfig,
): Promise<LoginVerificationResult> {
const result = await verifySignature({
eName: config.eName,
signature: config.signature,
payload: config.session,
registryBaseUrl: config.registryBaseUrl,
});

return {
valid: result.valid,
error: result.error,
publicKey: result.publicKey,
};
}
18 changes: 18 additions & 0 deletions packages/auth/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
3 changes: 3 additions & 0 deletions packages/ui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.svelte-kit
dist
1 change: 1 addition & 0 deletions packages/ui/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
8 changes: 8 additions & 0 deletions packages/ui/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}
16 changes: 16 additions & 0 deletions packages/ui/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"tailwind": {
"css": "src/app.css",
"baseColor": "slate"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils",
"ui": "$lib/components/ui",
"hooks": "$lib/hooks",
"lib": "$lib"
},
"typescript": true,
"registry": "https://shadcn-svelte.com/registry"
}
48 changes: 48 additions & 0 deletions packages/ui/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import prettier from 'eslint-config-prettier';
import { fileURLToPath } from 'node:url';
import { includeIgnoreFile } from '@eslint/compat';
import js from '@eslint/js';
import svelte from 'eslint-plugin-svelte';
import { defineConfig } from 'eslint/config';
import globals from 'globals';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';

const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));

export default defineConfig(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
prettier,
...svelte.configs.prettier,
{
languageOptions: {
globals: { ...globals.browser, ...globals.node }
},
rules: {
'no-undef': 'off',
'svelte/no-navigation-without-resolve': ['error', { ignoreLinks: true }],
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}
]
}
},
{
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
languageOptions: {
parserOptions: {
projectService: true,
extraFileExtensions: ['.svelte'],
parser: ts.parser,
svelteConfig
}
}
}
);
Loading
Loading