유머천국 코하비닷컴
https://cohabe.com/sisa/5060052

매크로 링플래쉬 끼고 접사

이걸 어디는 11만원에 팔더라구요 중국놈
알리는 더 비싸구요 이런 곳 널렸죠
내가 싸게 샀나보다 하고 물건 보니 거의 장난감에 가깝습니다
5~6만원에 팔아도 3만원은 남겠구나 합니다
3만원이면 어마하게 밝은 수술용 수준의 플래쉬 구입이 가능하죠 해루질 하는 거
여하간, 제 평은 그렇지만 실제로는 쇼핑몰 평은 좋습니다.
너무 가깝고 작은 것은 이도 필요가 없군요.
20251023_154603.jpg20251023_154358.jpg
피사체가 별로지만.. 장비 사진만 올리는 거 극혐하기에..
질문만 하는 인간도 제발 사라지길!!!
극혐하는 인간 부류
나르시시스트(자기애성 인격장애자=이기성 끝판왕)
1.거짓말 하는 인간
2.질문만 하는 인간
3.장비만 올리는 인간
4.받기만 하는 인간, 소통 불능자
5.피해를 가해로 둔갑 하는 인간
6.과대망상자와 고마움 모르는 인간
사람은 싫어도 사진 까지는 싫어하진 않습니다.
4R0A5834.JPG4R0A5833.JPG

댓글
  • nabiyang 2025/10/23 20:31

    피가로씨 접사도 하나요?

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:44

    정신병자들 ㅋㅋㅋ

    (GW1v9x)

  • nabiyang 2025/10/23 20:45

    과거 제게 한 행위를 반성 / 사과도 없이 계속 반복인가요.
    당신의 행위는 무섭고 두려우니 그만 해 주세요.

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:46

    개딸하는 짓 늘 그렇지 않습니까? ㅋㅋㅋ

    (GW1v9x)

  • nabiyang 2025/10/23 20:46

    과거 제게 한 행위를 반성 / 사과도 없이 계속 반복인가요.
    당신의 행위는 무섭고 두려우니 그만 해 주세요.

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:47

    ㅋㅋㅋㅋㅋ

    (GW1v9x)

  • nabiyang 2025/10/23 20:49

    과거 제게 한 행위를 반성 / 사과도 없이 계속 반복인가요.
    당신의 행위는 무섭고 두려우니 그만 해 주세요.

    (GW1v9x)

  • nabiyang 2025/10/23 20:50

    그만하여 달라는 제 요청을 명확히 인지하고도 반복하는군요.
    과거 제게 한 행위를 반성 / 사과도 없이 계속 반복인가요.
    당신의 행위는 무섭고 두려우니 그만 해 주세요.

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:50

    ㅋㅋㅋㅋㅋ

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:53

    이재명 개딸이 이렇게 위험함 ㄷㄷ

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:53

    // 파일: backend/authConfig.jsw
    // 역할: 모든 소셜 로그인 백엔드 로직을 통합 관리합니다.
    // - Secrets Manager에서 인증 정보를 로드합니다.
    // - 프런트엔드에 비민감 설정을 제공합니다.
    // - 토큰 교환, 사용자 프로필 조회, Wix 멤버 생성/로그인을 처리합니다.
    import { getSecret } from 'wix-secrets-backend';
    import { fetch } from 'wix-fetch';
    // ???? 최종 수정: 회원 관련 모든 기능은 'wix-members-backend'를 사용합니다.
    import { authentication, members } from 'wix-members-backend';
    import { SECRETS } from './util.jsw';
    // 설정 정보를 한 번만 로드하기 위한 캐시
    let configCache = null;
    /**
    * [내부 함수] Secrets Manager에서 모든 필수 키를 비동기적으로 로드하고 캐시합니다.
    */
    async function loadConfig() {
    if (configCache) {
    return configCache;
    }
    console.log("[DEBUG] loadConfig: Secrets Manager에서 설정 로드를 시작합니다.");
    try {
    const [
    kakaoClientId, kakaoClientSecret, naverClientId,
    naverClientSecret, kakaoRedirectUri, naverRedirectUri
    ] = await Promise.all([
    getSecret(SECRETS.KAKAO_REST_API_KEY),
    getSecret(SECRETS.KAKAO_CLIENT_SECRET),
    getSecret(SECRETS.NAVER_CLIENT_ID),
    getSecret(SECRETS.NAVER_CLIENT_SECRET),
    getSecret(SECRETS.KAKAO_REDIRECT_URI),
    getSecret(SECRETS.NAVER_REDIRECT_URI),
    ]);
    configCache = {
    kakao: {
    clientId: kakaoClientId, clientSecret: kakaoClientSecret, redirectUri: kakaoRedirectUri,
    authUrl: "https://kauth.kakao.com/oauth/authorize", tokenUrl: "https://kauth.kakao.com/oauth/token", profileUrl: "https://kapi.kakao.com/v2/user/me"
    },
    naver: {
    clientId: naverClientId, clientSecret: naverClientSecret, redirectUri: naverRedirectUri,
    authUrl: "https://nid.naver.com/oauth2.0/authorize", tokenUrl: "https://nid.naver.com/oauth2.0/token", profileUrl: "https://openapi.naver.com/v1/nid/me"
    }
    };
    console.log("[DEBUG] loadConfig: 모든 시크릿 로드 및 설정 구성 완료.");
    return configCache;
    } catch (error) {
    console.error("Secrets Manager에서 키 로드 중 치명적 오류 발생:", error);
    throw new Error("하나 이상의 필수 시크릿 키를 로드할 수 없습니다. Secret Manager의 키 이름과 값을 확인하세요.");
    }
    }
    /**
    * [프런트엔드 노출 함수] 로그인 버튼 생성에 필요한 비민감 설정 정보를 제공합니다.
    */
    export async function getClientAuthConfigs() {
    const config = await loadConfig();
    const clientConfigs = {};
    for (const provider in config) {
    clientConfigs[provider] = {
    clientId: config[provider].clientId,
    redirectUri: config[provider].redirectUri,
    authUrl: config[provider].authUrl
    };
    }
    return clientConfigs;
    }
    /**
    * [프런트엔드 노출 함수] 인가 코드를 받아 최종 Wix 멤버 세션을 생성합니다.
    */
    export async function getSessionToken(provider, code, state) {
    console.log(`[DEBUG] getSessionToken: 시작 - Provider: ${provider}`);
    try {
    const config = await loadConfig();
    const providerConfig = config[provider];
    if (!providerConfig) throw new Error(`지원되지 않는 Provider: ${provider}`);
    console.log("[DEBUG] 1. 토큰 교환 시작...");
    const tokenResponse = await exchangeToken(provider, code, state, providerConfig);
    const accessToken = tokenResponse.access_token;
    console.log("[DEBUG] 1. 토큰 교환 성공.");
    console.log("[DEBUG] 2. 사용자 프로필 조회 시작...");
    const userProfile = await getUserProfile(provider, accessToken, providerConfig);
    if (!userProfile || !userProfile.email) {
    throw new Error(`${provider} 계정에서 이메일 정보를 가져올 수 없습니다. 사용자 동의(스코프)를 확인하세요.`);
    }
    console.log(`[DEBUG] 2. 사용자 프로필 조회 성공: ${userProfile.email}`);
    console.log("[DEBUG] 3. Wix 멤버 가입 또는 로그인 처리 시작...");
    let sessionToken;
    let isNewUser = false;
    try {
    // ???? 최종 수정: 먼저 가입을 시도합니다.
    // 이 함수는 신규 사용자(연락처+멤버 생성)와 기존 연락처(멤버로 전환)를 모두 처리합니다.
    console.log("[DEBUG] 3a. 새 멤버로 등록 시도 (기존 연락처인 경우 멤버로 전환됨)...");
    const registrationResult = await authentication.register(userProfile.email, undefined, {
    contactInfo: { firstName: userProfile.name || '' }
    });
    sessionToken = registrationResult.sessionToken;
    isNewUser = true;
    console.log("[DEBUG] 4a. (새 멤버) Wix 멤버 등록 및 세션 토큰 생성 성공.");
    } catch (error) {
    // 가입이 실패한 경우, 이미 가입된 회원일 가능성이 높습니다.
    if (error.message && error.message.includes("member with this email already exists")) {
    console.log("[DEBUG] 3b. 이미 가입된 멤버 확인. 기존 멤버로 로그인 시도...");
    const queryResult = await members.queryMembers().eq("loginEmail", userProfile.email).find();
    if (queryResult.items.length > 0) {
    const member = queryResult.items[0];
    console.log("[DEBUG] 4b. (기존 멤버) Wix 세션 토큰 생성 시작...");
    sessionToken = await authentication.generateSessionToken(member._id);
    isNewUser = false;
    console.log("[DEBUG] 4b. (기존 멤버) Wix 세션 토큰 생성 성공.");
    } else {
    // 이 경우는 거의 발생하지 않지만, 등록 실패와 조회가 모두 안되는 예외 상황입니다.
    throw new Error("멤버가 이미 존재하여 등록에 실패했으나, 해당 멤버를 조회할 수 없습니다.");
    }
    } else {
    // 다른 종류의 가입 오류입니다.
    throw error;
    }
    }
    return { sessionToken, isNewUser };
    } catch (error) {
    console.error(`[${provider}] getSessionToken 처리 중 오류:`, error.message);
    return { error: error.message };
    }
    }
    // --- 내부 헬퍼 함수 ---
    async function exchangeToken(provider, code, state, config) {
    const response = await fetch(config.tokenUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' },
    body: new URLSearchParams({
    grant_type: 'authorization_code',
    client_id: config.clientId,
    client_secret: config.clientSecret,
    redirect_uri: config.redirectUri,
    code: code,
    ...(provider === 'naver' && { state: state })
    })
    });
    const data = await response.json();
    if (!response.ok) throw new Error(`토큰 교환 실패: ${data.error_description || JSON.stringify(data)}`);
    return data;
    }
    async function getUserProfile(provider, accessToken, config) {
    const response = await fetch(config.profileUrl, {
    headers: { 'Authorization': `Bearer ${accessToken}` }
    });
    const data = await response.json();
    if (!response.ok) throw new Error(`프로필 조회 실패: ${JSON.stringify(data)}`);
    if (provider === 'kakao') {
    return {
    email: data.kakao_account.email,
    name: data.kakao_account.profile.nickname
    };
    }
    if (provider === 'naver') {
    return {
    email: data.response.email,
    name: data.response.nickname
    };
    }
    }

    (GW1v9x)

  • nabiyang 2025/10/23 20:54

    과거 제게 한 행위를 반성 / 사과도 없이 계속 반복인가요.
    당신의 행위는 무섭고 두려우니 그만 해 주세요.

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:59

    ㅋㅋㅋㅋㅋ

    (GW1v9x)

  • ZENOSX™ 2025/10/23 20:59

    캐논의 현실! ㅋㅋㅋㅋㅋ

    (GW1v9x)

(GW1v9x)